mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-29 11:02:08 +00:00
Merge branch 'master' into starts_ends_with_utf8
This commit is contained in:
commit
d0c9425711
176
CHANGELOG.md
176
CHANGELOG.md
@ -1,4 +1,5 @@
|
|||||||
### Table of Contents
|
### Table of Contents
|
||||||
|
**[ClickHouse release v23.7, 2023-07-27](#237)**<br/>
|
||||||
**[ClickHouse release v23.6, 2023-06-30](#236)**<br/>
|
**[ClickHouse release v23.6, 2023-06-30](#236)**<br/>
|
||||||
**[ClickHouse release v23.5, 2023-06-08](#235)**<br/>
|
**[ClickHouse release v23.5, 2023-06-08](#235)**<br/>
|
||||||
**[ClickHouse release v23.4, 2023-04-26](#234)**<br/>
|
**[ClickHouse release v23.4, 2023-04-26](#234)**<br/>
|
||||||
@ -9,6 +10,181 @@
|
|||||||
|
|
||||||
# 2023 Changelog
|
# 2023 Changelog
|
||||||
|
|
||||||
|
### <a id="237"></a> ClickHouse release 23.7, 2023-07-27
|
||||||
|
|
||||||
|
#### Backward Incompatible Change
|
||||||
|
* Add `NAMED COLLECTION` access type (aliases `USE NAMED COLLECTION`, `NAMED COLLECTION USAGE`). This PR is backward incompatible because this access type is disabled by default (because a parent access type `NAMED COLLECTION ADMIN` is disabled by default as well). Proposed in [#50277](https://github.com/ClickHouse/ClickHouse/issues/50277). To grant use `GRANT NAMED COLLECTION ON collection_name TO user` or `GRANT NAMED COLLECTION ON * TO user`, to be able to give these grants `named_collection_admin` is required in config (previously it was named `named_collection_control`, so will remain as an alias). [#50625](https://github.com/ClickHouse/ClickHouse/pull/50625) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Fixing a typo in the `system.parts` column name `last_removal_attemp_time`. Now it is named `last_removal_attempt_time`. [#52104](https://github.com/ClickHouse/ClickHouse/pull/52104) ([filimonov](https://github.com/filimonov)).
|
||||||
|
* Bump version of the distributed_ddl_entry_format_version to 5 by default (enables opentelemetry and initial_query_idd pass through). This will not allow to process existing entries for distributed DDL after *downgrade* (but note, that usually there should be no such unprocessed entries). [#52128](https://github.com/ClickHouse/ClickHouse/pull/52128) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Check projection metadata the same way we check ordinary metadata. This change may prevent the server from starting in case there was a table with an invalid projection. An example is a projection that created positional columns in PK (e.g. `projection p (select * order by 1, 4)` which is not allowed in table PK and can cause a crash during insert/merge). Drop such projections before the update. Fixes [#52353](https://github.com/ClickHouse/ClickHouse/issues/52353). [#52361](https://github.com/ClickHouse/ClickHouse/pull/52361) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||||
|
* The experimental feature `hashid` is removed due to a bug. The quality of implementation was questionable at the start, and it didn't get through the experimental status. This closes [#52406](https://github.com/ClickHouse/ClickHouse/issues/52406). [#52449](https://github.com/ClickHouse/ClickHouse/pull/52449) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
|
||||||
|
#### New Feature
|
||||||
|
* Added `Overlay` database engine to combine multiple databases into one. Added `Filesystem` database engine to represent a directory in the filesystem as a set of implicitly available tables with auto-detected formats and structures. A new `S3` database engine allows to read-only interact with s3 storage by representing a prefix as a set of tables. A new `HDFS` database engine allows to interact with HDFS storage in the same way. [#48821](https://github.com/ClickHouse/ClickHouse/pull/48821) ([alekseygolub](https://github.com/alekseygolub)).
|
||||||
|
* Add support for external disks in Keeper for storing snapshots and logs. [#50098](https://github.com/ClickHouse/ClickHouse/pull/50098) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Add support for multi-directory selection (`{}`) globs. [#50559](https://github.com/ClickHouse/ClickHouse/pull/50559) ([Andrey Zvonov](https://github.com/zvonand)).
|
||||||
|
* Support ZooKeeper `reconfig` command for ClickHouse Keeper with incremental reconfiguration which can be enabled via `keeper_server.enable_reconfiguration` setting. Support adding servers, removing servers, and changing server priorities. [#49450](https://github.com/ClickHouse/ClickHouse/pull/49450) ([Mike Kot](https://github.com/myrrc)).
|
||||||
|
* Kafka connector can fetch Avro schema from schema registry with basic authentication using url-encoded credentials. [#49664](https://github.com/ClickHouse/ClickHouse/pull/49664) ([Ilya Golshtein](https://github.com/ilejn)).
|
||||||
|
* Add function `arrayJaccardIndex` which computes the Jaccard similarity between two arrays. [#50076](https://github.com/ClickHouse/ClickHouse/pull/50076) ([FFFFFFFHHHHHHH](https://github.com/FFFFFFFHHHHHHH)).
|
||||||
|
* Add a column `is_obsolete` to `system.settings` and similar tables. Closes [#50819](https://github.com/ClickHouse/ClickHouse/issues/50819). [#50826](https://github.com/ClickHouse/ClickHouse/pull/50826) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Implement support of encrypted elements in configuration file. Added possibility to use encrypted text in leaf elements of configuration file. The text is encrypted using encryption codecs from `<encryption_codecs>` section. [#50986](https://github.com/ClickHouse/ClickHouse/pull/50986) ([Roman Vasin](https://github.com/rvasin)).
|
||||||
|
* Grace Hash Join algorithm is now applicable to FULL and RIGHT JOINs. [#49483](https://github.com/ClickHouse/ClickHouse/issues/49483). [#51013](https://github.com/ClickHouse/ClickHouse/pull/51013) ([lgbo](https://github.com/lgbo-ustc)).
|
||||||
|
* Add `SYSTEM STOP LISTEN` query for more graceful termination. Closes [#47972](https://github.com/ClickHouse/ClickHouse/issues/47972). [#51016](https://github.com/ClickHouse/ClickHouse/pull/51016) ([Nikolay Degterinsky](https://github.com/evillique)).
|
||||||
|
* Add `input_format_csv_allow_variable_number_of_columns` options. [#51273](https://github.com/ClickHouse/ClickHouse/pull/51273) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Another boring feature: add function `substring_index`, as in Spark or MySQL. [#51472](https://github.com/ClickHouse/ClickHouse/pull/51472) ([李扬](https://github.com/taiyang-li)).
|
||||||
|
* A system table `jemalloc_bins` to show stats for jemalloc bins. Example `SELECT *, size * (nmalloc - ndalloc) AS allocated_bytes FROM system.jemalloc_bins WHERE allocated_bytes > 0 ORDER BY allocated_bytes DESC LIMIT 10`. Enjoy. [#51674](https://github.com/ClickHouse/ClickHouse/pull/51674) ([Alexander Gololobov](https://github.com/davenger)).
|
||||||
|
* Add `RowBinaryWithDefaults` format with extra byte before each column as a flag for using the column's default value. Closes [#50854](https://github.com/ClickHouse/ClickHouse/issues/50854). [#51695](https://github.com/ClickHouse/ClickHouse/pull/51695) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Added `default_temporary_table_engine` setting. Same as `default_table_engine` but for temporary tables. [#51292](https://github.com/ClickHouse/ClickHouse/issues/51292). [#51708](https://github.com/ClickHouse/ClickHouse/pull/51708) ([velavokr](https://github.com/velavokr)).
|
||||||
|
* Added new `initcap` / `initcapUTF8` functions which convert the first letter of each word to upper case and the rest to lower case. [#51735](https://github.com/ClickHouse/ClickHouse/pull/51735) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Create table now supports `PRIMARY KEY` syntax in column definition. Columns are added to primary index in the same order columns are defined. [#51881](https://github.com/ClickHouse/ClickHouse/pull/51881) ([Ilya Yatsishin](https://github.com/qoega)).
|
||||||
|
* Added the possibility to use date and time format specifiers in log and error log file names, either in config files (`log` and `errorlog` tags) or command line arguments (`--log-file` and `--errorlog-file`). [#51945](https://github.com/ClickHouse/ClickHouse/pull/51945) ([Victor Krasnov](https://github.com/sirvickr)).
|
||||||
|
* Added Peak Memory Usage statistic to HTTP headers. [#51946](https://github.com/ClickHouse/ClickHouse/pull/51946) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Added new `hasSubsequence` (+`CaseInsensitive` and `UTF8` versions) functions to match subsequences in strings. [#52050](https://github.com/ClickHouse/ClickHouse/pull/52050) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Add `array_agg` as alias of `groupArray` for PostgreSQL compatibility. Closes [#52100](https://github.com/ClickHouse/ClickHouse/issues/52100). ### Documentation entry for user-facing changes. [#52135](https://github.com/ClickHouse/ClickHouse/pull/52135) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Add `any_value` as a compatibility alias for `any` aggregate function. Closes [#52140](https://github.com/ClickHouse/ClickHouse/issues/52140). [#52147](https://github.com/ClickHouse/ClickHouse/pull/52147) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Add aggregate function `array_concat_agg` for compatibility with BigQuery, it's alias of `groupArrayArray`. Closes [#52139](https://github.com/ClickHouse/ClickHouse/issues/52139). [#52149](https://github.com/ClickHouse/ClickHouse/pull/52149) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Add `OCTET_LENGTH` as an alias to `length`. Closes [#52153](https://github.com/ClickHouse/ClickHouse/issues/52153). [#52176](https://github.com/ClickHouse/ClickHouse/pull/52176) ([FFFFFFFHHHHHHH](https://github.com/FFFFFFFHHHHHHH)).
|
||||||
|
* Added `firstLine` function to extract the first line from the multi-line string. This closes [#51172](https://github.com/ClickHouse/ClickHouse/issues/51172). [#52209](https://github.com/ClickHouse/ClickHouse/pull/52209) ([Mikhail Koviazin](https://github.com/mkmkme)).
|
||||||
|
* Implement KQL-style formatting for the `Interval` data type. This is only needed for compatibility with the `Kusto` query language. [#45671](https://github.com/ClickHouse/ClickHouse/pull/45671) ([ltrk2](https://github.com/ltrk2)).
|
||||||
|
* Added query `SYSTEM FLUSH ASYNC INSERT QUEUE` which flushes all pending asynchronous inserts to the destination tables. Added a server-side setting `async_insert_queue_flush_on_shutdown` (`true` by default) which determines whether to flush queue of asynchronous inserts on graceful shutdown. Setting `async_insert_threads` is now a server-side setting. [#49160](https://github.com/ClickHouse/ClickHouse/pull/49160) ([Anton Popov](https://github.com/CurtizJ)).
|
||||||
|
* Aliases `current_database` and a new function `current_schemas` for compatibility with PostgreSQL. [#51076](https://github.com/ClickHouse/ClickHouse/pull/51076) ([Pedro Riera](https://github.com/priera)).
|
||||||
|
* Add alias for functions `today` (now available under the `curdate`/`current_date` names) and `now` (`current_timestamp`). [#52106](https://github.com/ClickHouse/ClickHouse/pull/52106) ([Lloyd-Pottiger](https://github.com/Lloyd-Pottiger)).
|
||||||
|
* Support `async_deduplication_token` for async insert. [#52136](https://github.com/ClickHouse/ClickHouse/pull/52136) ([Han Fei](https://github.com/hanfei1991)).
|
||||||
|
* Add new setting `disable_url_encoding` that allows to disable decoding/encoding path in uri in URL engine. [#52337](https://github.com/ClickHouse/ClickHouse/pull/52337) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
|
||||||
|
#### Performance Improvement
|
||||||
|
* Writing parquet files is 10x faster, it's multi-threaded now. Almost the same speed as reading. [#49367](https://github.com/ClickHouse/ClickHouse/pull/49367) ([Michael Kolupaev](https://github.com/al13n321)).
|
||||||
|
* Enable automatic selection of the sparse serialization format by default. It improves performance. The format is supported since version 22.1. After this change, downgrading to versions older than 22.1 might not be possible. You can turn off the usage of the sparse serialization format by providing the `ratio_of_defaults_for_sparse_serialization = 1` setting for your MergeTree tables. [#49631](https://github.com/ClickHouse/ClickHouse/pull/49631) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Enable `move_all_conditions_to_prewhere` and `enable_multiple_prewhere_read_steps` settings by default. [#46365](https://github.com/ClickHouse/ClickHouse/pull/46365) ([Alexander Gololobov](https://github.com/davenger)).
|
||||||
|
* Improves performance of some queries by tuning allocator. [#46416](https://github.com/ClickHouse/ClickHouse/pull/46416) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Now we use fixed-size tasks in `MergeTreePrefetchedReadPool` as in `MergeTreeReadPool`. Also from now we use connection pool for S3 requests. [#49732](https://github.com/ClickHouse/ClickHouse/pull/49732) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* More pushdown to the right side of join. [#50532](https://github.com/ClickHouse/ClickHouse/pull/50532) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Improve grace_hash join by reserving hash table's size (resubmit). [#50875](https://github.com/ClickHouse/ClickHouse/pull/50875) ([lgbo](https://github.com/lgbo-ustc)).
|
||||||
|
* Waiting on lock in `OpenedFileCache` could be noticeable sometimes. We sharded it into multiple sub-maps (each with its own lock) to avoid contention. [#51341](https://github.com/ClickHouse/ClickHouse/pull/51341) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Move conditions with primary key columns to the end of PREWHERE chain. The idea is that conditions with PK columns are likely to be used in PK analysis and will not contribute much more to PREWHERE filtering. [#51958](https://github.com/ClickHouse/ClickHouse/pull/51958) ([Alexander Gololobov](https://github.com/davenger)).
|
||||||
|
* Speed up `COUNT(DISTINCT)` for String types by inlining SipHash. The performance experiments of *OnTime* on the ICX device (Intel Xeon Platinum 8380 CPU, 80 cores, 160 threads) show that this change could bring an improvement of *11.6%* to the QPS of the query *Q8* while having no impact on others. [#52036](https://github.com/ClickHouse/ClickHouse/pull/52036) ([Zhiguo Zhou](https://github.com/ZhiguoZh)).
|
||||||
|
* Enable `allow_vertical_merges_from_compact_to_wide_parts` by default. It will save memory usage during merges. [#52295](https://github.com/ClickHouse/ClickHouse/pull/52295) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix incorrect projection analysis which invalidates primary keys. This issue only exists when `query_plan_optimize_primary_key = 1, query_plan_optimize_projection = 1`. This fixes [#48823](https://github.com/ClickHouse/ClickHouse/issues/48823). This fixes [#51173](https://github.com/ClickHouse/ClickHouse/issues/51173). [#52308](https://github.com/ClickHouse/ClickHouse/pull/52308) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* Reduce the number of syscalls in `FileCache::loadMetadata` - this speeds up server startup if the filesystem cache is configured. [#52435](https://github.com/ClickHouse/ClickHouse/pull/52435) ([Raúl Marín](https://github.com/Algunenano)).
|
||||||
|
* Allow to have strict lower boundary for file segment size by downloading remaining data in the background. Minimum size of file segment (if actual file size is bigger) is configured as cache configuration setting `boundary_alignment`, by default `4Mi`. Number of background threads are configured as cache configuration setting `background_download_threads`, by default `2`. Also `max_file_segment_size` was increased from `8Mi` to `32Mi` in this PR. [#51000](https://github.com/ClickHouse/ClickHouse/pull/51000) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Decreased default timeouts for S3 from 30 seconds to 3 seconds, and for other HTTP from 180 seconds to 30 seconds. [#51171](https://github.com/ClickHouse/ClickHouse/pull/51171) ([Michael Kolupaev](https://github.com/al13n321)).
|
||||||
|
* New setting `merge_tree_determine_task_size_by_prewhere_columns` added. If set to `true` only sizes of the columns from `PREWHERE` section will be considered to determine reading task size. Otherwise all the columns from query are considered. [#52606](https://github.com/ClickHouse/ClickHouse/pull/52606) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
|
||||||
|
#### Improvement
|
||||||
|
* Use read_bytes/total_bytes_to_read for progress bar in s3/file/url/... table functions for better progress indication. [#51286](https://github.com/ClickHouse/ClickHouse/pull/51286) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Introduce a table setting `wait_for_unique_parts_send_before_shutdown_ms` which specify the amount of time replica will wait before closing interserver handler for replicated sends. Also fix inconsistency with shutdown of tables and interserver handlers: now server shutdown tables first and only after it shut down interserver handlers. [#51851](https://github.com/ClickHouse/ClickHouse/pull/51851) ([alesapin](https://github.com/alesapin)).
|
||||||
|
* Allow SQL standard `FETCH` without `OFFSET`. See https://antonz.org/sql-fetch/. [#51293](https://github.com/ClickHouse/ClickHouse/pull/51293) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Allow filtering HTTP headers for the URL/S3 table functions with the new `http_forbid_headers` section in config. Both exact matching and regexp filters are available. [#51038](https://github.com/ClickHouse/ClickHouse/pull/51038) ([Nikolay Degterinsky](https://github.com/evillique)).
|
||||||
|
* Don't show messages about `16 EiB` free space in logs, as they don't make sense. This closes [#49320](https://github.com/ClickHouse/ClickHouse/issues/49320). [#49342](https://github.com/ClickHouse/ClickHouse/pull/49342) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Properly check the limit for the `sleepEachRow` function. Add a setting `function_sleep_max_microseconds_per_block`. This is needed for generic query fuzzer. [#49343](https://github.com/ClickHouse/ClickHouse/pull/49343) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix two issues in `geoHash` functions. [#50066](https://github.com/ClickHouse/ClickHouse/pull/50066) ([李扬](https://github.com/taiyang-li)).
|
||||||
|
* Log async insert flush queries into `system.query_log`. [#51160](https://github.com/ClickHouse/ClickHouse/pull/51160) ([Raúl Marín](https://github.com/Algunenano)).
|
||||||
|
* Functions `date_diff` and `age` now support millisecond/microsecond unit and work with microsecond precision. [#51291](https://github.com/ClickHouse/ClickHouse/pull/51291) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Improve parsing of path in clickhouse-keeper-client. [#51359](https://github.com/ClickHouse/ClickHouse/pull/51359) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* A third-party product depending on ClickHouse (Gluten: a Plugin to Double SparkSQL's Performance) had a bug. This fix avoids heap overflow in that third-party product while reading from HDFS. [#51386](https://github.com/ClickHouse/ClickHouse/pull/51386) ([李扬](https://github.com/taiyang-li)).
|
||||||
|
* Add ability to disable native copy for S3 (setting for BACKUP/RESTORE `allow_s3_native_copy`, and `s3_allow_native_copy` for `s3`/`s3_plain` disks). [#51448](https://github.com/ClickHouse/ClickHouse/pull/51448) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Add column `primary_key_size` to `system.parts` table to show compressed primary key size on disk. Closes [#51400](https://github.com/ClickHouse/ClickHouse/issues/51400). [#51496](https://github.com/ClickHouse/ClickHouse/pull/51496) ([Yarik Briukhovetskyi](https://github.com/yariks5s)).
|
||||||
|
* Allow running `clickhouse-local` without procfs, without home directory existing, and without name resolution plugins from glibc. [#51518](https://github.com/ClickHouse/ClickHouse/pull/51518) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Add placeholder `%a` for rull filename in rename_files_after_processing setting. [#51603](https://github.com/ClickHouse/ClickHouse/pull/51603) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Add column `modification_time` into `system.parts_columns`. [#51685](https://github.com/ClickHouse/ClickHouse/pull/51685) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Add new setting `input_format_csv_use_default_on_bad_values` to CSV format that allows to insert default value when parsing of a single field failed. [#51716](https://github.com/ClickHouse/ClickHouse/pull/51716) ([KevinyhZou](https://github.com/KevinyhZou)).
|
||||||
|
* Added a crash log flush to the disk after the unexpected crash. [#51720](https://github.com/ClickHouse/ClickHouse/pull/51720) ([Alexey Gerasimchuck](https://github.com/Demilivor)).
|
||||||
|
* Fix behavior in dashboard page where errors unrelated to authentication are not shown. Also fix 'overlapping' chart behavior. [#51744](https://github.com/ClickHouse/ClickHouse/pull/51744) ([Zach Naimon](https://github.com/ArctypeZach)).
|
||||||
|
* Allow UUID to UInt128 conversion. [#51765](https://github.com/ClickHouse/ClickHouse/pull/51765) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Added support for function `range` of Nullable arguments. [#51767](https://github.com/ClickHouse/ClickHouse/pull/51767) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Convert condition like `toyear(x) = c` to `c1 <= x < c2`. [#51795](https://github.com/ClickHouse/ClickHouse/pull/51795) ([Han Fei](https://github.com/hanfei1991)).
|
||||||
|
* Improve MySQL compatibility of the statement `SHOW INDEX`. [#51796](https://github.com/ClickHouse/ClickHouse/pull/51796) ([Robert Schulze](https://github.com/rschu1ze)).
|
||||||
|
* Fix `use_structure_from_insertion_table_in_table_functions` does not work with `MATERIALIZED` and `ALIAS` columns. Closes [#51817](https://github.com/ClickHouse/ClickHouse/issues/51817). Closes [#51019](https://github.com/ClickHouse/ClickHouse/issues/51019). [#51825](https://github.com/ClickHouse/ClickHouse/pull/51825) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Cache dictionary now requests only unique keys from source. Closes [#51762](https://github.com/ClickHouse/ClickHouse/issues/51762). [#51853](https://github.com/ClickHouse/ClickHouse/pull/51853) ([Maksim Kita](https://github.com/kitaisreal)).
|
||||||
|
* Fixed the case when settings were not applied for EXPLAIN query when FORMAT was provided. [#51859](https://github.com/ClickHouse/ClickHouse/pull/51859) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Allow SETTINGS before FORMAT in DESCRIBE TABLE query for compatibility with SELECT query. Closes [#51544](https://github.com/ClickHouse/ClickHouse/issues/51544). [#51899](https://github.com/ClickHouse/ClickHouse/pull/51899) ([Nikolay Degterinsky](https://github.com/evillique)).
|
||||||
|
* Var-Int encoded integers (e.g. used by the native protocol) can now use the full 64-bit range. 3rd party clients are advised to update their var-int code accordingly. [#51905](https://github.com/ClickHouse/ClickHouse/pull/51905) ([Robert Schulze](https://github.com/rschu1ze)).
|
||||||
|
* Update certificates when they change without the need to manually SYSTEM RELOAD CONFIG. [#52030](https://github.com/ClickHouse/ClickHouse/pull/52030) ([Mike Kot](https://github.com/myrrc)).
|
||||||
|
* Added `allow_create_index_without_type` setting that allow to ignore `ADD INDEX` queries without specified `TYPE`. Standard SQL queries will just succeed without changing table schema. [#52056](https://github.com/ClickHouse/ClickHouse/pull/52056) ([Ilya Yatsishin](https://github.com/qoega)).
|
||||||
|
* Log messages are written to the `system.text_log` from the server startup. [#52113](https://github.com/ClickHouse/ClickHouse/pull/52113) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* In cases where the HTTP endpoint has multiple IP addresses and the first of them is unreachable, a timeout exception was thrown. Made session creation with handling all resolved endpoints. [#52116](https://github.com/ClickHouse/ClickHouse/pull/52116) ([Aleksei Filatov](https://github.com/aalexfvk)).
|
||||||
|
* Avro input format now supports Union even if it contains only a single type. Closes [#52131](https://github.com/ClickHouse/ClickHouse/issues/52131). [#52137](https://github.com/ClickHouse/ClickHouse/pull/52137) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Add setting `optimize_use_implicit_projections` to disable implicit projections (currently only `min_max_count` projection). [#52152](https://github.com/ClickHouse/ClickHouse/pull/52152) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* It was possible to use the function `hasToken` for infinite loop. Now this possibility is removed. This closes [#52156](https://github.com/ClickHouse/ClickHouse/issues/52156). [#52160](https://github.com/ClickHouse/ClickHouse/pull/52160) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Create ZK ancestors optimistically. [#52195](https://github.com/ClickHouse/ClickHouse/pull/52195) ([Raúl Marín](https://github.com/Algunenano)).
|
||||||
|
* Fix [#50582](https://github.com/ClickHouse/ClickHouse/issues/50582). Avoid the `Not found column ... in block` error in some cases of reading in-order and constants. [#52259](https://github.com/ClickHouse/ClickHouse/pull/52259) ([Chen768959](https://github.com/Chen768959)).
|
||||||
|
* Check whether S2 geo primitives are invalid as early as possible on ClickHouse side. This closes: [#27090](https://github.com/ClickHouse/ClickHouse/issues/27090). [#52260](https://github.com/ClickHouse/ClickHouse/pull/52260) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
|
||||||
|
* Add back missing projection QueryAccessInfo when `query_plan_optimize_projection = 1`. This fixes [#50183](https://github.com/ClickHouse/ClickHouse/issues/50183) . This fixes [#50093](https://github.com/ClickHouse/ClickHouse/issues/50093). [#52327](https://github.com/ClickHouse/ClickHouse/pull/52327) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* When `ZooKeeperRetriesControl` rethrows an error, it's more useful to see its original stack trace, not the one from `ZooKeeperRetriesControl` itself. [#52347](https://github.com/ClickHouse/ClickHouse/pull/52347) ([Vitaly Baranov](https://github.com/vitlibar)).
|
||||||
|
* Wait for zero copy replication lock even if some disks don't support it. [#52376](https://github.com/ClickHouse/ClickHouse/pull/52376) ([Raúl Marín](https://github.com/Algunenano)).
|
||||||
|
* Now interserver port will be closed only after tables are shut down. [#52498](https://github.com/ClickHouse/ClickHouse/pull/52498) ([alesapin](https://github.com/alesapin)).
|
||||||
|
|
||||||
|
#### Experimental Feature
|
||||||
|
* Added support for [PRQL](https://prql-lang.org/) as a query language. [#50686](https://github.com/ClickHouse/ClickHouse/pull/50686) ([János Benjamin Antal](https://github.com/antaljanosbenjamin)).
|
||||||
|
* Allow to add disk name for custom disks. Previously custom disks would use an internal generated disk name. Now it will be possible with `disk = disk_<name>(...)` (e.g. disk will have name `name`) . [#51552](https://github.com/ClickHouse/ClickHouse/pull/51552) ([Kseniia Sumarokova](https://github.com/kssenii)). This syntax can be changed in this release.
|
||||||
|
* (experimental MaterializedMySQL) Fixed crash when `mysqlxx::Pool::Entry` is used after it was disconnected. [#52063](https://github.com/ClickHouse/ClickHouse/pull/52063) ([Val Doroshchuk](https://github.com/valbok)).
|
||||||
|
* (experimental MaterializedMySQL) `CREATE TABLE ... AS SELECT` .. is now supported in MaterializedMySQL. [#52067](https://github.com/ClickHouse/ClickHouse/pull/52067) ([Val Doroshchuk](https://github.com/valbok)).
|
||||||
|
* (experimental MaterializedMySQL) Introduced automatic conversion of text types to utf8 for MaterializedMySQL. [#52084](https://github.com/ClickHouse/ClickHouse/pull/52084) ([Val Doroshchuk](https://github.com/valbok)).
|
||||||
|
* (experimental MaterializedMySQL) Now unquoted UTF-8 strings are supported in DDL for MaterializedMySQL. [#52318](https://github.com/ClickHouse/ClickHouse/pull/52318) ([Val Doroshchuk](https://github.com/valbok)).
|
||||||
|
* (experimental MaterializedMySQL) Now double quoted comments are supported in MaterializedMySQL. [#52355](https://github.com/ClickHouse/ClickHouse/pull/52355) ([Val Doroshchuk](https://github.com/valbok)).
|
||||||
|
* Upgrade Intel QPL from v1.1.0 to v1.2.0 2. Upgrade Intel accel-config from v3.5 to v4.0 3. Fixed issue that Device IOTLB miss has big perf. impact for IAA accelerators. [#52180](https://github.com/ClickHouse/ClickHouse/pull/52180) ([jasperzhu](https://github.com/jinjunzh)).
|
||||||
|
* The `session_timezone` setting (new in version 23.6) is demoted to experimental. [#52445](https://github.com/ClickHouse/ClickHouse/pull/52445) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
|
||||||
|
#### Build/Testing/Packaging Improvement
|
||||||
|
* Add experimental ClickHouse builds for Linux RISC-V 64 to CI. [#31398](https://github.com/ClickHouse/ClickHouse/pull/31398) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Add integration test check with the enabled Analyzer. [#50926](https://github.com/ClickHouse/ClickHouse/pull/50926) [#52210](https://github.com/ClickHouse/ClickHouse/pull/52210) ([Dmitry Novik](https://github.com/novikd)).
|
||||||
|
* Reproducible builds for Rust. [#52395](https://github.com/ClickHouse/ClickHouse/pull/52395) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Update Cargo dependencies. [#51721](https://github.com/ClickHouse/ClickHouse/pull/51721) ([Raúl Marín](https://github.com/Algunenano)).
|
||||||
|
* Make the function `CHColumnToArrowColumn::fillArrowArrayWithArrayColumnData` to work with nullable arrays, which are not possible in ClickHouse, but needed for Gluten. [#52112](https://github.com/ClickHouse/ClickHouse/pull/52112) ([李扬](https://github.com/taiyang-li)).
|
||||||
|
* We've updated the CCTZ library to master, but there are no user-visible changes. [#52124](https://github.com/ClickHouse/ClickHouse/pull/52124) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* The `system.licenses` table now includes the hard-forked library Poco. This closes [#52066](https://github.com/ClickHouse/ClickHouse/issues/52066). [#52127](https://github.com/ClickHouse/ClickHouse/pull/52127) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Check that there are no cases of bad punctuation: whitespace before a comma like `Hello ,world` instead of `Hello, world`. [#52549](https://github.com/ClickHouse/ClickHouse/pull/52549) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
|
||||||
|
#### Bug Fix (user-visible misbehavior in an official stable release)
|
||||||
|
* Fix MaterializedPostgreSQL syncTables [#49698](https://github.com/ClickHouse/ClickHouse/pull/49698) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Fix projection with optimize_aggregators_of_group_by_keys [#49709](https://github.com/ClickHouse/ClickHouse/pull/49709) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* Fix optimize_skip_unused_shards with JOINs [#51037](https://github.com/ClickHouse/ClickHouse/pull/51037) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix formatDateTime() with fractional negative datetime64 [#51290](https://github.com/ClickHouse/ClickHouse/pull/51290) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Functions `hasToken*` were totally wrong. Add a test for [#43358](https://github.com/ClickHouse/ClickHouse/issues/43358) [#51378](https://github.com/ClickHouse/ClickHouse/pull/51378) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix optimization to move functions before sorting. [#51481](https://github.com/ClickHouse/ClickHouse/pull/51481) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||||
|
* Fix Block structure mismatch in Pipe::unitePipes for FINAL [#51492](https://github.com/ClickHouse/ClickHouse/pull/51492) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Fix SIGSEGV for clusters with zero weight across all shards (fixes INSERT INTO FUNCTION clusterAllReplicas()) [#51545](https://github.com/ClickHouse/ClickHouse/pull/51545) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix timeout for hedged requests [#51582](https://github.com/ClickHouse/ClickHouse/pull/51582) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix logical error in ANTI join with NULL [#51601](https://github.com/ClickHouse/ClickHouse/pull/51601) ([vdimir](https://github.com/vdimir)).
|
||||||
|
* Fix for moving 'IN' conditions to PREWHERE [#51610](https://github.com/ClickHouse/ClickHouse/pull/51610) ([Alexander Gololobov](https://github.com/davenger)).
|
||||||
|
* Do not apply PredicateExpressionsOptimizer for ASOF/ANTI join [#51633](https://github.com/ClickHouse/ClickHouse/pull/51633) ([vdimir](https://github.com/vdimir)).
|
||||||
|
* Fix async insert with deduplication for ReplicatedMergeTree using merging algorithms [#51676](https://github.com/ClickHouse/ClickHouse/pull/51676) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Fix reading from empty column in `parseSipHashKey` [#51804](https://github.com/ClickHouse/ClickHouse/pull/51804) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Fix segfault when create invalid EmbeddedRocksdb table [#51847](https://github.com/ClickHouse/ClickHouse/pull/51847) ([Duc Canh Le](https://github.com/canhld94)).
|
||||||
|
* Fix inserts into MongoDB tables [#51876](https://github.com/ClickHouse/ClickHouse/pull/51876) ([Nikolay Degterinsky](https://github.com/evillique)).
|
||||||
|
* Fix deadlock on DatabaseCatalog shutdown [#51908](https://github.com/ClickHouse/ClickHouse/pull/51908) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Fix error in subquery operators [#51922](https://github.com/ClickHouse/ClickHouse/pull/51922) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix async connect to hosts with multiple ips [#51934](https://github.com/ClickHouse/ClickHouse/pull/51934) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Do not remove inputs after ActionsDAG::merge [#51947](https://github.com/ClickHouse/ClickHouse/pull/51947) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||||
|
* Check refcount in `RemoveManyObjectStorageOperation::finalize` instead of `execute` [#51954](https://github.com/ClickHouse/ClickHouse/pull/51954) ([vdimir](https://github.com/vdimir)).
|
||||||
|
* Allow parametric UDFs [#51964](https://github.com/ClickHouse/ClickHouse/pull/51964) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Small fix for toDateTime64() for dates after 2283-12-31 [#52130](https://github.com/ClickHouse/ClickHouse/pull/52130) ([Andrey Zvonov](https://github.com/zvonand)).
|
||||||
|
* Fix ORDER BY tuple of WINDOW functions [#52145](https://github.com/ClickHouse/ClickHouse/pull/52145) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix incorrect projection analysis when aggregation expression contains monotonic functions [#52151](https://github.com/ClickHouse/ClickHouse/pull/52151) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* Fix error in `groupArrayMoving` functions [#52161](https://github.com/ClickHouse/ClickHouse/pull/52161) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Disable direct join for range dictionary [#52187](https://github.com/ClickHouse/ClickHouse/pull/52187) ([Duc Canh Le](https://github.com/canhld94)).
|
||||||
|
* Fix sticky mutations test (and extremely rare race condition) [#52197](https://github.com/ClickHouse/ClickHouse/pull/52197) ([alesapin](https://github.com/alesapin)).
|
||||||
|
* Fix race in Web disk [#52211](https://github.com/ClickHouse/ClickHouse/pull/52211) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Fix data race in Connection::setAsyncCallback on unknown packet from server [#52219](https://github.com/ClickHouse/ClickHouse/pull/52219) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Fix temp data deletion on startup, add test [#52275](https://github.com/ClickHouse/ClickHouse/pull/52275) ([vdimir](https://github.com/vdimir)).
|
||||||
|
* Don't use minmax_count projections when counting nullable columns [#52297](https://github.com/ClickHouse/ClickHouse/pull/52297) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* MergeTree/ReplicatedMergeTree should use server timezone for log entries [#52325](https://github.com/ClickHouse/ClickHouse/pull/52325) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix parameterized view with cte and multiple usage [#52328](https://github.com/ClickHouse/ClickHouse/pull/52328) ([SmitaRKulkarni](https://github.com/SmitaRKulkarni)).
|
||||||
|
* Disable expression templates for time intervals [#52335](https://github.com/ClickHouse/ClickHouse/pull/52335) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Fix `apply_snapshot` in Keeper [#52358](https://github.com/ClickHouse/ClickHouse/pull/52358) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Update build-osx.md [#52377](https://github.com/ClickHouse/ClickHouse/pull/52377) ([AlexBykovski](https://github.com/AlexBykovski)).
|
||||||
|
* Fix `countSubstrings()` hang with empty needle and a column haystack [#52409](https://github.com/ClickHouse/ClickHouse/pull/52409) ([Sergei Trifonov](https://github.com/serxa)).
|
||||||
|
* Fix normal projection with merge table [#52432](https://github.com/ClickHouse/ClickHouse/pull/52432) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* Fix possible double-free in Aggregator [#52439](https://github.com/ClickHouse/ClickHouse/pull/52439) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Fixed inserting into Buffer engine [#52440](https://github.com/ClickHouse/ClickHouse/pull/52440) ([Vasily Nemkov](https://github.com/Enmk)).
|
||||||
|
* The implementation of AnyHash was non-conformant. [#52448](https://github.com/ClickHouse/ClickHouse/pull/52448) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Check recursion depth in OptimizedRegularExpression [#52451](https://github.com/ClickHouse/ClickHouse/pull/52451) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix data-race DatabaseReplicated::startupTables()/canExecuteReplicatedMetadataAlter() [#52490](https://github.com/ClickHouse/ClickHouse/pull/52490) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix abort in function `transform` [#52513](https://github.com/ClickHouse/ClickHouse/pull/52513) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix lightweight delete after drop of projection [#52517](https://github.com/ClickHouse/ClickHouse/pull/52517) ([Anton Popov](https://github.com/CurtizJ)).
|
||||||
|
* Fix possible error "Cannot drain connections: cancel first" [#52585](https://github.com/ClickHouse/ClickHouse/pull/52585) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
|
||||||
|
|
||||||
### <a id="236"></a> ClickHouse release 23.6, 2023-06-29
|
### <a id="236"></a> ClickHouse release 23.6, 2023-06-29
|
||||||
|
|
||||||
#### Backward Incompatible Change
|
#### Backward Incompatible Change
|
||||||
|
@ -13,9 +13,10 @@ The following versions of ClickHouse server are currently being supported with s
|
|||||||
|
|
||||||
| Version | Supported |
|
| Version | Supported |
|
||||||
|:-|:-|
|
|:-|:-|
|
||||||
|
| 23.7 | ✔️ |
|
||||||
| 23.6 | ✔️ |
|
| 23.6 | ✔️ |
|
||||||
| 23.5 | ✔️ |
|
| 23.5 | ✔️ |
|
||||||
| 23.4 | ✔️ |
|
| 23.4 | ❌ |
|
||||||
| 23.3 | ✔️ |
|
| 23.3 | ✔️ |
|
||||||
| 23.2 | ❌ |
|
| 23.2 | ❌ |
|
||||||
| 23.1 | ❌ |
|
| 23.1 | ❌ |
|
||||||
|
@ -67,6 +67,8 @@ public:
|
|||||||
|
|
||||||
Message(
|
Message(
|
||||||
const std::string & source, const std::string & text, Priority prio, const char * file, int line, std::string_view fmt_str = {});
|
const std::string & source, const std::string & text, Priority prio, const char * file, int line, std::string_view fmt_str = {});
|
||||||
|
Message(
|
||||||
|
std::string && source, std::string && text, Priority prio, const char * file, int line, std::string_view fmt_str);
|
||||||
/// Creates a Message with the given source, text, priority,
|
/// Creates a Message with the given source, text, priority,
|
||||||
/// source file path and line.
|
/// source file path and line.
|
||||||
///
|
///
|
||||||
|
@ -57,7 +57,7 @@ public:
|
|||||||
URI();
|
URI();
|
||||||
/// Creates an empty URI.
|
/// Creates an empty URI.
|
||||||
|
|
||||||
explicit URI(const std::string & uri);
|
explicit URI(const std::string & uri, bool disable_url_encoding = false);
|
||||||
/// Parses an URI from the given string. Throws a
|
/// Parses an URI from the given string. Throws a
|
||||||
/// SyntaxException if the uri is not valid.
|
/// SyntaxException if the uri is not valid.
|
||||||
|
|
||||||
@ -350,6 +350,10 @@ protected:
|
|||||||
static const std::string ILLEGAL;
|
static const std::string ILLEGAL;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void encodePath(std::string & encodedStr) const;
|
||||||
|
void decodePath(const std::string & encodedStr);
|
||||||
|
|
||||||
|
|
||||||
std::string _scheme;
|
std::string _scheme;
|
||||||
std::string _userInfo;
|
std::string _userInfo;
|
||||||
std::string _host;
|
std::string _host;
|
||||||
@ -357,6 +361,8 @@ private:
|
|||||||
std::string _path;
|
std::string _path;
|
||||||
std::string _query;
|
std::string _query;
|
||||||
std::string _fragment;
|
std::string _fragment;
|
||||||
|
|
||||||
|
bool _disable_url_encoding = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,6 +60,19 @@ Message::Message(const std::string& source, const std::string& text, Priority pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Message::Message(std::string && source, std::string && text, Priority prio, const char * file, int line, std::string_view fmt_str):
|
||||||
|
_source(std::move(source)),
|
||||||
|
_text(std::move(text)),
|
||||||
|
_prio(prio),
|
||||||
|
_tid(0),
|
||||||
|
_file(file),
|
||||||
|
_line(line),
|
||||||
|
_pMap(0),
|
||||||
|
_fmt_str(fmt_str)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
Message::Message(const Message& msg):
|
Message::Message(const Message& msg):
|
||||||
_source(msg._source),
|
_source(msg._source),
|
||||||
_text(msg._text),
|
_text(msg._text),
|
||||||
|
@ -36,8 +36,8 @@ URI::URI():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
URI::URI(const std::string& uri):
|
URI::URI(const std::string& uri, bool decode_and_encode_path):
|
||||||
_port(0)
|
_port(0), _disable_url_encoding(decode_and_encode_path)
|
||||||
{
|
{
|
||||||
parse(uri);
|
parse(uri);
|
||||||
}
|
}
|
||||||
@ -107,7 +107,8 @@ URI::URI(const URI& uri):
|
|||||||
_port(uri._port),
|
_port(uri._port),
|
||||||
_path(uri._path),
|
_path(uri._path),
|
||||||
_query(uri._query),
|
_query(uri._query),
|
||||||
_fragment(uri._fragment)
|
_fragment(uri._fragment),
|
||||||
|
_disable_url_encoding(uri._disable_url_encoding)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +120,8 @@ URI::URI(const URI& baseURI, const std::string& relativeURI):
|
|||||||
_port(baseURI._port),
|
_port(baseURI._port),
|
||||||
_path(baseURI._path),
|
_path(baseURI._path),
|
||||||
_query(baseURI._query),
|
_query(baseURI._query),
|
||||||
_fragment(baseURI._fragment)
|
_fragment(baseURI._fragment),
|
||||||
|
_disable_url_encoding(baseURI._disable_url_encoding)
|
||||||
{
|
{
|
||||||
resolve(relativeURI);
|
resolve(relativeURI);
|
||||||
}
|
}
|
||||||
@ -151,6 +153,7 @@ URI& URI::operator = (const URI& uri)
|
|||||||
_path = uri._path;
|
_path = uri._path;
|
||||||
_query = uri._query;
|
_query = uri._query;
|
||||||
_fragment = uri._fragment;
|
_fragment = uri._fragment;
|
||||||
|
_disable_url_encoding = uri._disable_url_encoding;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -181,6 +184,7 @@ void URI::swap(URI& uri)
|
|||||||
std::swap(_path, uri._path);
|
std::swap(_path, uri._path);
|
||||||
std::swap(_query, uri._query);
|
std::swap(_query, uri._query);
|
||||||
std::swap(_fragment, uri._fragment);
|
std::swap(_fragment, uri._fragment);
|
||||||
|
std::swap(_disable_url_encoding, uri._disable_url_encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -201,7 +205,7 @@ std::string URI::toString() const
|
|||||||
std::string uri;
|
std::string uri;
|
||||||
if (isRelative())
|
if (isRelative())
|
||||||
{
|
{
|
||||||
encode(_path, RESERVED_PATH, uri);
|
encodePath(uri);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -217,7 +221,7 @@ std::string URI::toString() const
|
|||||||
{
|
{
|
||||||
if (!auth.empty() && _path[0] != '/')
|
if (!auth.empty() && _path[0] != '/')
|
||||||
uri += '/';
|
uri += '/';
|
||||||
encode(_path, RESERVED_PATH, uri);
|
encodePath(uri);
|
||||||
}
|
}
|
||||||
else if (!_query.empty() || !_fragment.empty())
|
else if (!_query.empty() || !_fragment.empty())
|
||||||
{
|
{
|
||||||
@ -313,7 +317,7 @@ void URI::setAuthority(const std::string& authority)
|
|||||||
void URI::setPath(const std::string& path)
|
void URI::setPath(const std::string& path)
|
||||||
{
|
{
|
||||||
_path.clear();
|
_path.clear();
|
||||||
decode(path, _path);
|
decodePath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -418,7 +422,7 @@ void URI::setPathEtc(const std::string& pathEtc)
|
|||||||
std::string URI::getPathEtc() const
|
std::string URI::getPathEtc() const
|
||||||
{
|
{
|
||||||
std::string pathEtc;
|
std::string pathEtc;
|
||||||
encode(_path, RESERVED_PATH, pathEtc);
|
encodePath(pathEtc);
|
||||||
if (!_query.empty())
|
if (!_query.empty())
|
||||||
{
|
{
|
||||||
pathEtc += '?';
|
pathEtc += '?';
|
||||||
@ -436,7 +440,7 @@ std::string URI::getPathEtc() const
|
|||||||
std::string URI::getPathAndQuery() const
|
std::string URI::getPathAndQuery() const
|
||||||
{
|
{
|
||||||
std::string pathAndQuery;
|
std::string pathAndQuery;
|
||||||
encode(_path, RESERVED_PATH, pathAndQuery);
|
encodePath(pathAndQuery);
|
||||||
if (!_query.empty())
|
if (!_query.empty())
|
||||||
{
|
{
|
||||||
pathAndQuery += '?';
|
pathAndQuery += '?';
|
||||||
@ -681,6 +685,21 @@ void URI::decode(const std::string& str, std::string& decodedStr, bool plusAsSpa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void URI::encodePath(std::string & encodedStr) const
|
||||||
|
{
|
||||||
|
if (_disable_url_encoding)
|
||||||
|
encodedStr = _path;
|
||||||
|
else
|
||||||
|
encode(_path, RESERVED_PATH, encodedStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void URI::decodePath(const std::string & encodedStr)
|
||||||
|
{
|
||||||
|
if (_disable_url_encoding)
|
||||||
|
_path = encodedStr;
|
||||||
|
else
|
||||||
|
decode(encodedStr, _path);
|
||||||
|
}
|
||||||
|
|
||||||
bool URI::isWellKnownPort() const
|
bool URI::isWellKnownPort() const
|
||||||
{
|
{
|
||||||
@ -820,7 +839,7 @@ void URI::parsePath(std::string::const_iterator& it, const std::string::const_it
|
|||||||
{
|
{
|
||||||
std::string path;
|
std::string path;
|
||||||
while (it != end && *it != '?' && *it != '#') path += *it++;
|
while (it != end && *it != '?' && *it != '#') path += *it++;
|
||||||
decode(path, _path);
|
decodePath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
# NOTE: has nothing common with DBMS_TCP_PROTOCOL_VERSION,
|
# NOTE: has nothing common with DBMS_TCP_PROTOCOL_VERSION,
|
||||||
# only DBMS_TCP_PROTOCOL_VERSION should be incremented on protocol changes.
|
# only DBMS_TCP_PROTOCOL_VERSION should be incremented on protocol changes.
|
||||||
SET(VERSION_REVISION 54476)
|
SET(VERSION_REVISION 54477)
|
||||||
SET(VERSION_MAJOR 23)
|
SET(VERSION_MAJOR 23)
|
||||||
SET(VERSION_MINOR 7)
|
SET(VERSION_MINOR 8)
|
||||||
SET(VERSION_PATCH 1)
|
SET(VERSION_PATCH 1)
|
||||||
SET(VERSION_GITHASH d1c7e13d08868cb04d3562dcced704dd577cb1df)
|
SET(VERSION_GITHASH a70127baecc451f1f7073bad7b6198f6703441d8)
|
||||||
SET(VERSION_DESCRIBE v23.7.1.1-testing)
|
SET(VERSION_DESCRIBE v23.8.1.1-testing)
|
||||||
SET(VERSION_STRING 23.7.1.1)
|
SET(VERSION_STRING 23.8.1.1)
|
||||||
# end of autochange
|
# end of autochange
|
||||||
|
@ -502,9 +502,10 @@ target_include_directories(_parquet SYSTEM BEFORE
|
|||||||
"${ClickHouse_SOURCE_DIR}/contrib/arrow/cpp/src"
|
"${ClickHouse_SOURCE_DIR}/contrib/arrow/cpp/src"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/cpp/src")
|
"${CMAKE_CURRENT_SOURCE_DIR}/cpp/src")
|
||||||
target_link_libraries(_parquet
|
target_link_libraries(_parquet
|
||||||
PUBLIC _arrow
|
PUBLIC
|
||||||
PRIVATE
|
_arrow
|
||||||
ch_contrib::thrift
|
ch_contrib::thrift
|
||||||
|
PRIVATE
|
||||||
boost::headers_only
|
boost::headers_only
|
||||||
boost::regex
|
boost::regex
|
||||||
OpenSSL::Crypto OpenSSL::SSL)
|
OpenSSL::Crypto OpenSSL::SSL)
|
||||||
|
2
contrib/idxd-config
vendored
2
contrib/idxd-config
vendored
@ -1 +1 @@
|
|||||||
Subproject commit f6605c41a735e3fdfef2d2d18655a33af6490b99
|
Subproject commit a836ce0e42052a69bffbbc14239ab4097f3b77f1
|
2
contrib/qpl
vendored
2
contrib/qpl
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 3f8f5cea27739f5261e8fd577dc233ffe88bf679
|
Subproject commit faaf19350459c076e66bb5df11743c3fade59b73
|
@ -32,7 +32,7 @@ RUN arch=${TARGETARCH:-amd64} \
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
ARG REPOSITORY="https://s3.amazonaws.com/clickhouse-builds/22.4/31c367d3cd3aefd316778601ff6565119fe36682/package_release"
|
ARG REPOSITORY="https://s3.amazonaws.com/clickhouse-builds/22.4/31c367d3cd3aefd316778601ff6565119fe36682/package_release"
|
||||||
ARG VERSION="23.6.2.18"
|
ARG VERSION="23.7.1.2470"
|
||||||
ARG PACKAGES="clickhouse-keeper"
|
ARG PACKAGES="clickhouse-keeper"
|
||||||
|
|
||||||
# user/group precreated explicitly with fixed uid/gid on purpose.
|
# user/group precreated explicitly with fixed uid/gid on purpose.
|
||||||
|
@ -33,7 +33,7 @@ RUN arch=${TARGETARCH:-amd64} \
|
|||||||
# lts / testing / prestable / etc
|
# lts / testing / prestable / etc
|
||||||
ARG REPO_CHANNEL="stable"
|
ARG REPO_CHANNEL="stable"
|
||||||
ARG REPOSITORY="https://packages.clickhouse.com/tgz/${REPO_CHANNEL}"
|
ARG REPOSITORY="https://packages.clickhouse.com/tgz/${REPO_CHANNEL}"
|
||||||
ARG VERSION="23.6.2.18"
|
ARG VERSION="23.7.1.2470"
|
||||||
ARG PACKAGES="clickhouse-client clickhouse-server clickhouse-common-static"
|
ARG PACKAGES="clickhouse-client clickhouse-server clickhouse-common-static"
|
||||||
|
|
||||||
# user/group precreated explicitly with fixed uid/gid on purpose.
|
# user/group precreated explicitly with fixed uid/gid on purpose.
|
||||||
|
@ -23,7 +23,7 @@ RUN sed -i "s|http://archive.ubuntu.com|${apt_archive}|g" /etc/apt/sources.list
|
|||||||
|
|
||||||
ARG REPO_CHANNEL="stable"
|
ARG REPO_CHANNEL="stable"
|
||||||
ARG REPOSITORY="deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg] https://packages.clickhouse.com/deb ${REPO_CHANNEL} main"
|
ARG REPOSITORY="deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg] https://packages.clickhouse.com/deb ${REPO_CHANNEL} main"
|
||||||
ARG VERSION="23.6.2.18"
|
ARG VERSION="23.7.1.2470"
|
||||||
ARG PACKAGES="clickhouse-client clickhouse-server clickhouse-common-static"
|
ARG PACKAGES="clickhouse-client clickhouse-server clickhouse-common-static"
|
||||||
|
|
||||||
# set non-empty deb_location_url url to create a docker image
|
# set non-empty deb_location_url url to create a docker image
|
||||||
|
@ -14,6 +14,7 @@ ln -s /usr/share/clickhouse-test/clickhouse-test /usr/bin/clickhouse-test
|
|||||||
|
|
||||||
# Stress tests and upgrade check uses similar code that was placed
|
# Stress tests and upgrade check uses similar code that was placed
|
||||||
# in a separate bash library. See tests/ci/stress_tests.lib
|
# in a separate bash library. See tests/ci/stress_tests.lib
|
||||||
|
source /usr/share/clickhouse-test/ci/attach_gdb.lib
|
||||||
source /usr/share/clickhouse-test/ci/stress_tests.lib
|
source /usr/share/clickhouse-test/ci/stress_tests.lib
|
||||||
|
|
||||||
install_packages package_folder
|
install_packages package_folder
|
||||||
@ -52,7 +53,7 @@ azurite-blob --blobHost 0.0.0.0 --blobPort 10000 --debug /azurite_log &
|
|||||||
|
|
||||||
start
|
start
|
||||||
|
|
||||||
shellcheck disable=SC2086 # No quotes because I want to split it into words.
|
# shellcheck disable=SC2086 # No quotes because I want to split it into words.
|
||||||
/s3downloader --url-prefix "$S3_URL" --dataset-names $DATASETS
|
/s3downloader --url-prefix "$S3_URL" --dataset-names $DATASETS
|
||||||
chmod 777 -R /var/lib/clickhouse
|
chmod 777 -R /var/lib/clickhouse
|
||||||
clickhouse-client --query "ATTACH DATABASE IF NOT EXISTS datasets ENGINE = Ordinary"
|
clickhouse-client --query "ATTACH DATABASE IF NOT EXISTS datasets ENGINE = Ordinary"
|
||||||
|
@ -16,6 +16,7 @@ ln -s /usr/share/clickhouse-test/ci/get_previous_release_tag.py /usr/bin/get_pre
|
|||||||
|
|
||||||
# Stress tests and upgrade check uses similar code that was placed
|
# Stress tests and upgrade check uses similar code that was placed
|
||||||
# in a separate bash library. See tests/ci/stress_tests.lib
|
# in a separate bash library. See tests/ci/stress_tests.lib
|
||||||
|
source /usr/share/clickhouse-test/ci/attach_gdb.lib
|
||||||
source /usr/share/clickhouse-test/ci/stress_tests.lib
|
source /usr/share/clickhouse-test/ci/stress_tests.lib
|
||||||
|
|
||||||
azurite-blob --blobHost 0.0.0.0 --blobPort 10000 --debug /azurite_log &
|
azurite-blob --blobHost 0.0.0.0 --blobPort 10000 --debug /azurite_log &
|
||||||
@ -61,6 +62,7 @@ configure
|
|||||||
|
|
||||||
# it contains some new settings, but we can safely remove it
|
# it contains some new settings, but we can safely remove it
|
||||||
rm /etc/clickhouse-server/config.d/merge_tree.xml
|
rm /etc/clickhouse-server/config.d/merge_tree.xml
|
||||||
|
rm /etc/clickhouse-server/config.d/enable_wait_for_shutdown_replicated_tables.xml
|
||||||
rm /etc/clickhouse-server/users.d/nonconst_timezone.xml
|
rm /etc/clickhouse-server/users.d/nonconst_timezone.xml
|
||||||
|
|
||||||
start
|
start
|
||||||
@ -90,6 +92,7 @@ sudo chgrp clickhouse /etc/clickhouse-server/config.d/s3_storage_policy_by_defau
|
|||||||
|
|
||||||
# it contains some new settings, but we can safely remove it
|
# it contains some new settings, but we can safely remove it
|
||||||
rm /etc/clickhouse-server/config.d/merge_tree.xml
|
rm /etc/clickhouse-server/config.d/merge_tree.xml
|
||||||
|
rm /etc/clickhouse-server/config.d/enable_wait_for_shutdown_replicated_tables.xml
|
||||||
rm /etc/clickhouse-server/users.d/nonconst_timezone.xml
|
rm /etc/clickhouse-server/users.d/nonconst_timezone.xml
|
||||||
|
|
||||||
start
|
start
|
||||||
|
452
docs/changelogs/v23.7.1.2470-stable.md
Normal file
452
docs/changelogs/v23.7.1.2470-stable.md
Normal file
@ -0,0 +1,452 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 1
|
||||||
|
sidebar_label: 2023
|
||||||
|
---
|
||||||
|
|
||||||
|
# 2023 Changelog
|
||||||
|
|
||||||
|
### ClickHouse release v23.7.1.2470-stable (a70127baecc) FIXME as compared to v23.6.1.1524-stable (d1c7e13d088)
|
||||||
|
|
||||||
|
#### Backward Incompatible Change
|
||||||
|
* Add ` NAMED COLLECTION` access type (aliases `USE NAMED COLLECTION`, `NAMED COLLECTION USAGE`). This PR is backward incompatible because this access type is disabled by default (because a parent access type `NAMED COLLECTION ADMIN` is disabled by default as well). Proposed in [#50277](https://github.com/ClickHouse/ClickHouse/issues/50277). To grant use `GRANT NAMED COLLECTION ON collection_name TO user` or `GRANT NAMED COLLECTION ON * TO user`, to be able to give these grants `named_collection_admin` is required in config (previously it was named `named_collection_control`, so will remain as an alias). [#50625](https://github.com/ClickHouse/ClickHouse/pull/50625) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Fixing a typo in the `system.parts` column name `last_removal_attemp_time`. Now it is named `last_removal_attempt_time`. [#52104](https://github.com/ClickHouse/ClickHouse/pull/52104) ([filimonov](https://github.com/filimonov)).
|
||||||
|
* Bump version of the distributed_ddl_entry_format_version to 5 by default (enables opentelemetry and initial_query_idd pass through). This will not allow to process existing entries for distributed DDL after **downgrade** (but note, that usually there should be no such unprocessed entries). [#52128](https://github.com/ClickHouse/ClickHouse/pull/52128) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Check projection metadata the same way we check ordinary metadata. This change may prevent the server from starting in case there was a table with an invalid projection. An example is a projection that created positional columns in PK (e.g. `projection p (select * order by 1, 4)` which is not allowed in table PK and can cause a crash during insert/merge). Drop such projections before the update. Fixes [#52353](https://github.com/ClickHouse/ClickHouse/issues/52353). [#52361](https://github.com/ClickHouse/ClickHouse/pull/52361) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||||
|
* The experimental feature `hashid` is removed due to a bug. The quality of implementation was questionable at the start, and it didn't get through the experimental status. This closes [#52406](https://github.com/ClickHouse/ClickHouse/issues/52406). [#52449](https://github.com/ClickHouse/ClickHouse/pull/52449) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* The function `toDecimalString` is removed due to subpar implementation quality. This closes [#52407](https://github.com/ClickHouse/ClickHouse/issues/52407). [#52450](https://github.com/ClickHouse/ClickHouse/pull/52450) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
|
||||||
|
#### New Feature
|
||||||
|
* Implement KQL-style formatting for Interval. [#45671](https://github.com/ClickHouse/ClickHouse/pull/45671) ([ltrk2](https://github.com/ltrk2)).
|
||||||
|
* Support ZooKeeper `reconfig` command for CH Keeper with incremental reconfiguration which can be enabled via `keeper_server.enable_reconfiguration` setting. Support adding servers, removing servers, and changing server priorities. [#49450](https://github.com/ClickHouse/ClickHouse/pull/49450) ([Mike Kot](https://github.com/myrrc)).
|
||||||
|
* Kafka connector can fetch avro schema from schema registry with basic authentication using url-encoded credentials. [#49664](https://github.com/ClickHouse/ClickHouse/pull/49664) ([Ilya Golshtein](https://github.com/ilejn)).
|
||||||
|
* Add function `arrayJaccardIndex` which computes the Jaccard similarity between two arrays. [#50076](https://github.com/ClickHouse/ClickHouse/pull/50076) ([FFFFFFFHHHHHHH](https://github.com/FFFFFFFHHHHHHH)).
|
||||||
|
* Added support for prql as a query language. [#50686](https://github.com/ClickHouse/ClickHouse/pull/50686) ([János Benjamin Antal](https://github.com/antaljanosbenjamin)).
|
||||||
|
* Add a column is_obsolete to system.settings and similar tables. Closes [#50819](https://github.com/ClickHouse/ClickHouse/issues/50819). [#50826](https://github.com/ClickHouse/ClickHouse/pull/50826) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Implement support of encrypted elements in configuration file Added possibility to use encrypted text in leaf elements of configuration file. The text is encrypted using encryption codecs from <encryption_codecs> section. [#50986](https://github.com/ClickHouse/ClickHouse/pull/50986) ([Roman Vasin](https://github.com/rvasin)).
|
||||||
|
* Just a new request of [#49483](https://github.com/ClickHouse/ClickHouse/issues/49483). [#51013](https://github.com/ClickHouse/ClickHouse/pull/51013) ([lgbo](https://github.com/lgbo-ustc)).
|
||||||
|
* Add SYSTEM STOP LISTEN query. Closes [#47972](https://github.com/ClickHouse/ClickHouse/issues/47972). [#51016](https://github.com/ClickHouse/ClickHouse/pull/51016) ([Nikolay Degterinsky](https://github.com/evillique)).
|
||||||
|
* Add input_format_csv_allow_variable_number_of_columns options. [#51273](https://github.com/ClickHouse/ClickHouse/pull/51273) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Another boring feature: add function substring_index, as in spark or mysql. [#51472](https://github.com/ClickHouse/ClickHouse/pull/51472) ([李扬](https://github.com/taiyang-li)).
|
||||||
|
* Show stats for jemalloc bins. Example ``` SELECT *, size * (nmalloc - ndalloc) AS allocated_bytes FROM system.jemalloc_bins WHERE allocated_bytes > 0 ORDER BY allocated_bytes DESC LIMIT 10. [#51674](https://github.com/ClickHouse/ClickHouse/pull/51674) ([Alexander Gololobov](https://github.com/davenger)).
|
||||||
|
* Add RowBinaryWithDefaults format with extra byte before each column for using column default value. Closes [#50854](https://github.com/ClickHouse/ClickHouse/issues/50854). [#51695](https://github.com/ClickHouse/ClickHouse/pull/51695) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Added `default_temporary_table_engine` setting. Same as `default_table_engine` but for temporary tables. [#51292](https://github.com/ClickHouse/ClickHouse/issues/51292). [#51708](https://github.com/ClickHouse/ClickHouse/pull/51708) ([velavokr](https://github.com/velavokr)).
|
||||||
|
* Added new initcap / initcapUTF8 functions which convert the first letter of each word to upper case and the rest to lower case. [#51735](https://github.com/ClickHouse/ClickHouse/pull/51735) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Create table now supports `PRIMARY KEY` syntax in column definition. Columns are added to primary index in the same order columns are defined. [#51881](https://github.com/ClickHouse/ClickHouse/pull/51881) ([Ilya Yatsishin](https://github.com/qoega)).
|
||||||
|
* Added the possibility to use date and time format specifiers in log and error log file names, either in config files (`log` and `errorlog` tags) or command line arguments (`--log-file` and `--errorlog-file`). [#51945](https://github.com/ClickHouse/ClickHouse/pull/51945) ([Victor Krasnov](https://github.com/sirvickr)).
|
||||||
|
* Added Peak Memory Usage (for query) to client final statistics, and to http header. [#51946](https://github.com/ClickHouse/ClickHouse/pull/51946) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Added new hasSubsequence() (+CaseInsensitive + UTF8 versions) functions. [#52050](https://github.com/ClickHouse/ClickHouse/pull/52050) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Add `array_agg` as alias of `groupArray` for PostgreSQL compatibility. Closes [#52100](https://github.com/ClickHouse/ClickHouse/issues/52100). ### Documentation entry for user-facing changes. [#52135](https://github.com/ClickHouse/ClickHouse/pull/52135) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Add `any_value` as a compatibility alias for `any` aggregate function. Closes [#52140](https://github.com/ClickHouse/ClickHouse/issues/52140). [#52147](https://github.com/ClickHouse/ClickHouse/pull/52147) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Add aggregate function `array_concat_agg` for compatibility with BigQuery, it's alias of `groupArrayArray`. Closes [#52139](https://github.com/ClickHouse/ClickHouse/issues/52139). [#52149](https://github.com/ClickHouse/ClickHouse/pull/52149) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Add `OCTET_LENGTH` as an alias to `length`. Closes [#52153](https://github.com/ClickHouse/ClickHouse/issues/52153). [#52176](https://github.com/ClickHouse/ClickHouse/pull/52176) ([FFFFFFFHHHHHHH](https://github.com/FFFFFFFHHHHHHH)).
|
||||||
|
* Re-add SipHash keyed functions. [#52206](https://github.com/ClickHouse/ClickHouse/pull/52206) ([Salvatore Mesoraca](https://github.com/aiven-sal)).
|
||||||
|
* Added `firstLine` function to extract the first line from the multi-line string. This closes [#51172](https://github.com/ClickHouse/ClickHouse/issues/51172). [#52209](https://github.com/ClickHouse/ClickHouse/pull/52209) ([Mikhail Koviazin](https://github.com/mkmkme)).
|
||||||
|
|
||||||
|
#### Performance Improvement
|
||||||
|
* Enable `move_all_conditions_to_prewhere` and `enable_multiple_prewhere_read_steps` settings by default. [#46365](https://github.com/ClickHouse/ClickHouse/pull/46365) ([Alexander Gololobov](https://github.com/davenger)).
|
||||||
|
* Improves performance of some queries by tuning allocator. [#46416](https://github.com/ClickHouse/ClickHouse/pull/46416) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Writing parquet files is 10x faster, it's multi-threaded now. Almost the same speed as reading. [#49367](https://github.com/ClickHouse/ClickHouse/pull/49367) ([Michael Kolupaev](https://github.com/al13n321)).
|
||||||
|
* Enable automatic selection of the sparse serialization format by default. It improves performance. The format is supported since version 22.1. After this change, downgrading to versions older than 22.1 might not be possible. You can turn off the usage of the sparse serialization format by providing the `ratio_of_defaults_for_sparse_serialization = 1` setting for your MergeTree tables. [#49631](https://github.com/ClickHouse/ClickHouse/pull/49631) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Now we use fixed-size tasks in `MergeTreePrefetchedReadPool` as in `MergeTreeReadPool`. Also from now we use connection pool for S3 requests. [#49732](https://github.com/ClickHouse/ClickHouse/pull/49732) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* More pushdown to the right side of join. [#50532](https://github.com/ClickHouse/ClickHouse/pull/50532) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Improve grace_hash join by reserving hash table's size (resubmit). [#50875](https://github.com/ClickHouse/ClickHouse/pull/50875) ([lgbo](https://github.com/lgbo-ustc)).
|
||||||
|
* Waiting on lock in `OpenedFileCache` could be noticeable sometimes. We sharded it into multiple sub-maps (each with its own lock) to avoid contention. [#51341](https://github.com/ClickHouse/ClickHouse/pull/51341) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Remove duplicate condition in functionunixtimestamp64.h. [#51857](https://github.com/ClickHouse/ClickHouse/pull/51857) ([lcjh](https://github.com/ljhcage)).
|
||||||
|
* The idea is that conditions with PK columns are likely to be used in PK analysis and will not contribute much more to PREWHERE filtering. [#51958](https://github.com/ClickHouse/ClickHouse/pull/51958) ([Alexander Gololobov](https://github.com/davenger)).
|
||||||
|
* 1. Add rewriter for both old and new analyzer. 2. Add settings `optimize_uniq_to_count` which default is 0. [#52004](https://github.com/ClickHouse/ClickHouse/pull/52004) ([JackyWoo](https://github.com/JackyWoo)).
|
||||||
|
* The performance experiments of **OnTime** on the ICX device (Intel Xeon Platinum 8380 CPU, 80 cores, 160 threads) show that this change could bring an improvement of **11.6%** to the QPS of the query **Q8** while having no impact on others. [#52036](https://github.com/ClickHouse/ClickHouse/pull/52036) ([Zhiguo Zhou](https://github.com/ZhiguoZh)).
|
||||||
|
* Enable `allow_vertical_merges_from_compact_to_wide_parts` by default. It will save memory usage during merges. [#52295](https://github.com/ClickHouse/ClickHouse/pull/52295) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix incorrect projection analysis which invalidates primary keys. This issue only exists when `query_plan_optimize_primary_key = 1, query_plan_optimize_projection = 1` . This fixes [#48823](https://github.com/ClickHouse/ClickHouse/issues/48823) . This fixes [#51173](https://github.com/ClickHouse/ClickHouse/issues/51173) . [#52308](https://github.com/ClickHouse/ClickHouse/pull/52308) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* Reduce the number of syscalls in FileCache::loadMetadata. [#52435](https://github.com/ClickHouse/ClickHouse/pull/52435) ([Raúl Marín](https://github.com/Algunenano)).
|
||||||
|
|
||||||
|
#### Improvement
|
||||||
|
* Added query `SYSTEM FLUSH ASYNC INSERT QUEUE` which flushes all pending asynchronous inserts to the destination tables. Added a server-side setting `async_insert_queue_flush_on_shutdown` (`true` by default) which determines whether to flush queue of asynchronous inserts on graceful shutdown. Setting `async_insert_threads` is now a server-side setting. [#49160](https://github.com/ClickHouse/ClickHouse/pull/49160) ([Anton Popov](https://github.com/CurtizJ)).
|
||||||
|
* Don't show messages about `16 EiB` free space in logs, as they don't make sense. This closes [#49320](https://github.com/ClickHouse/ClickHouse/issues/49320). [#49342](https://github.com/ClickHouse/ClickHouse/pull/49342) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Properly check the limit for the `sleepEachRow` function. Add a setting `function_sleep_max_microseconds_per_block`. This is needed for generic query fuzzer. [#49343](https://github.com/ClickHouse/ClickHouse/pull/49343) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix two issues: ``` select geohashEncode(120.2, number::Float64) from numbers(10);. [#50066](https://github.com/ClickHouse/ClickHouse/pull/50066) ([李扬](https://github.com/taiyang-li)).
|
||||||
|
* Add support for external disks in Keeper for storing snapshots and logs. [#50098](https://github.com/ClickHouse/ClickHouse/pull/50098) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Add support for multi-directory selection (`{}`) globs. [#50559](https://github.com/ClickHouse/ClickHouse/pull/50559) ([Andrey Zvonov](https://github.com/zvonand)).
|
||||||
|
* Allow to have strict lower boundary for file segment size by downloading remaining data in the background. Minimum size of file segment (if actual file size is bigger) is configured as cache configuration setting `boundary_alignment`, by default `4Mi`. Number of background threads are configured as cache configuration setting `background_download_threads`, by default `2`. Also `max_file_segment_size` was increased from `8Mi` to `32Mi` in this PR. [#51000](https://github.com/ClickHouse/ClickHouse/pull/51000) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Allow filtering HTTP headers with `http_forbid_headers` section in config. Both exact matching and regexp filters are available. [#51038](https://github.com/ClickHouse/ClickHouse/pull/51038) ([Nikolay Degterinsky](https://github.com/evillique)).
|
||||||
|
* #50727 new alias for function current_database and added new function current_schemas. [#51076](https://github.com/ClickHouse/ClickHouse/pull/51076) ([Pedro Riera](https://github.com/priera)).
|
||||||
|
* Log async insert flush queries into to system.query_log. [#51160](https://github.com/ClickHouse/ClickHouse/pull/51160) ([Raúl Marín](https://github.com/Algunenano)).
|
||||||
|
* Decreased default timeouts for S3 from 30 seconds to 3 seconds, and for other HTTP from 180 seconds to 30 seconds. [#51171](https://github.com/ClickHouse/ClickHouse/pull/51171) ([Michael Kolupaev](https://github.com/al13n321)).
|
||||||
|
* Use read_bytes/total_bytes_to_read for progress bar in s3/file/url/... table functions for better progress indication. [#51286](https://github.com/ClickHouse/ClickHouse/pull/51286) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Functions "date_diff() and age()" now support millisecond/microsecond unit and work with microsecond precision. [#51291](https://github.com/ClickHouse/ClickHouse/pull/51291) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Allow SQL standard `FETCH` without `OFFSET`. See https://antonz.org/sql-fetch/. [#51293](https://github.com/ClickHouse/ClickHouse/pull/51293) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Improve parsing of path in clickhouse-keeper-client. [#51359](https://github.com/ClickHouse/ClickHouse/pull/51359) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* A third-party product depending on ClickHouse (Gluten: Plugin to Double SparkSQL's Performance) had a bug. This fix avoids heap overflow in that third-party product while reading from HDFS. [#51386](https://github.com/ClickHouse/ClickHouse/pull/51386) ([李扬](https://github.com/taiyang-li)).
|
||||||
|
* Fix checking error caused by uninitialized class members. [#51418](https://github.com/ClickHouse/ClickHouse/pull/51418) ([李扬](https://github.com/taiyang-li)).
|
||||||
|
* Add ability to disable native copy for S3 (setting for BACKUP/RESTORE `allow_s3_native_copy`, and `s3_allow_native_copy` for `s3`/`s3_plain` disks). [#51448](https://github.com/ClickHouse/ClickHouse/pull/51448) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Add column `primary_key_size` to `system.parts` table to show compressed primary key size on disk. Closes [#51400](https://github.com/ClickHouse/ClickHouse/issues/51400). [#51496](https://github.com/ClickHouse/ClickHouse/pull/51496) ([Yarik Briukhovetskyi](https://github.com/yariks5s)).
|
||||||
|
* Allow running `clickhouse-local` without procfs, without home directory existing, and without name resolution plugins from glibc. [#51518](https://github.com/ClickHouse/ClickHouse/pull/51518) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Correcting the message of modify storage policy https://github.com/clickhouse/clickhouse/issues/51516 ### documentation entry for user-facing changes. [#51519](https://github.com/ClickHouse/ClickHouse/pull/51519) ([xiaolei565](https://github.com/xiaolei565)).
|
||||||
|
* Support `DROP FILESYSTEM CACHE <cache_name> KEY <key> [ OFFSET <offset>]`. [#51547](https://github.com/ClickHouse/ClickHouse/pull/51547) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Allow to add disk name for custom disks. Previously custom disks would use an internal generated disk name. Now it will be possible with `disk = disk_<name>(...)` (e.g. disk will have name `name`) . [#51552](https://github.com/ClickHouse/ClickHouse/pull/51552) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Add placeholder `%a` for rull filename in rename_files_after_processing setting. [#51603](https://github.com/ClickHouse/ClickHouse/pull/51603) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Add column modification time into system.parts_columns. [#51685](https://github.com/ClickHouse/ClickHouse/pull/51685) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Add new setting `input_format_csv_use_default_on_bad_values` to CSV format that allows to insert default value when parsing of a single field failed. [#51716](https://github.com/ClickHouse/ClickHouse/pull/51716) ([KevinyhZou](https://github.com/KevinyhZou)).
|
||||||
|
* Added a crash log flush to the disk after the unexpected crash. [#51720](https://github.com/ClickHouse/ClickHouse/pull/51720) ([Alexey Gerasimchuck](https://github.com/Demilivor)).
|
||||||
|
* Fix behavior in dashboard page where errors unrelated to authentication are not shown. Also fix 'overlapping' chart behavior. [#51744](https://github.com/ClickHouse/ClickHouse/pull/51744) ([Zach Naimon](https://github.com/ArctypeZach)).
|
||||||
|
* Allow UUID to UInt128 conversion. [#51765](https://github.com/ClickHouse/ClickHouse/pull/51765) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Added support for function range of Nullable arguments. [#51767](https://github.com/ClickHouse/ClickHouse/pull/51767) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Convert condition like `toyear(x) = c` to `c1 <= x < c2`. [#51795](https://github.com/ClickHouse/ClickHouse/pull/51795) ([Han Fei](https://github.com/hanfei1991)).
|
||||||
|
* Improve MySQL compatibility of statement SHOW INDEX. [#51796](https://github.com/ClickHouse/ClickHouse/pull/51796) ([Robert Schulze](https://github.com/rschu1ze)).
|
||||||
|
* Fix `use_structure_from_insertion_table_in_table_functions` does not work with `MATERIALIZED` and `ALIAS` columns. Closes [#51817](https://github.com/ClickHouse/ClickHouse/issues/51817). Closes [#51019](https://github.com/ClickHouse/ClickHouse/issues/51019). [#51825](https://github.com/ClickHouse/ClickHouse/pull/51825) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Introduce a table setting `wait_for_unique_parts_send_before_shutdown_ms` which specify the amount of time replica will wait before closing interserver handler for replicated sends. Also fix inconsistency with shutdown of tables and interserver handlers: now server shutdown tables first and only after it shut down interserver handlers. [#51851](https://github.com/ClickHouse/ClickHouse/pull/51851) ([alesapin](https://github.com/alesapin)).
|
||||||
|
* CacheDictionary request only unique keys from source. Closes [#51762](https://github.com/ClickHouse/ClickHouse/issues/51762). [#51853](https://github.com/ClickHouse/ClickHouse/pull/51853) ([Maksim Kita](https://github.com/kitaisreal)).
|
||||||
|
* Fixed settings not applied for explain query when format provided. [#51859](https://github.com/ClickHouse/ClickHouse/pull/51859) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Allow SETTINGS before FORMAT in DESCRIBE TABLE query for compatibility with SELECT query. Closes [#51544](https://github.com/ClickHouse/ClickHouse/issues/51544). [#51899](https://github.com/ClickHouse/ClickHouse/pull/51899) ([Nikolay Degterinsky](https://github.com/evillique)).
|
||||||
|
* Var-int encoded integers (e.g. used by the native protocol) can now use the full 64-bit range. 3rd party clients are advised to update their var-int code accordingly. [#51905](https://github.com/ClickHouse/ClickHouse/pull/51905) ([Robert Schulze](https://github.com/rschu1ze)).
|
||||||
|
* Update certificates when they change without the need to manually SYSTEM RELOAD CONFIG. [#52030](https://github.com/ClickHouse/ClickHouse/pull/52030) ([Mike Kot](https://github.com/myrrc)).
|
||||||
|
* Added `allow_create_index_without_type` setting that allow to ignore `ADD INDEX` queries without specified `TYPE`. Standard SQL queries will just succeed without changing table schema. [#52056](https://github.com/ClickHouse/ClickHouse/pull/52056) ([Ilya Yatsishin](https://github.com/qoega)).
|
||||||
|
* Fixed crash when mysqlxx::Pool::Entry is used after it was disconnected. [#52063](https://github.com/ClickHouse/ClickHouse/pull/52063) ([Val Doroshchuk](https://github.com/valbok)).
|
||||||
|
* CREATE TABLE ... AS SELECT .. is now supported in MaterializedMySQL. [#52067](https://github.com/ClickHouse/ClickHouse/pull/52067) ([Val Doroshchuk](https://github.com/valbok)).
|
||||||
|
* Introduced automatic conversion of text types to utf8 for MaterializedMySQL. [#52084](https://github.com/ClickHouse/ClickHouse/pull/52084) ([Val Doroshchuk](https://github.com/valbok)).
|
||||||
|
* Add alias for functions `today` (now available under the `curdate`/`current_date` names) and `now` (`current_timestamp`). [#52106](https://github.com/ClickHouse/ClickHouse/pull/52106) ([Lloyd-Pottiger](https://github.com/Lloyd-Pottiger)).
|
||||||
|
* Log messages are written to text_log from the beginning. [#52113](https://github.com/ClickHouse/ClickHouse/pull/52113) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* In cases where the HTTP endpoint has multiple IP addresses and the first of them is unreachable, a timeout exception will be thrown. Made session creation with handling all resolved endpoints. [#52116](https://github.com/ClickHouse/ClickHouse/pull/52116) ([Aleksei Filatov](https://github.com/aalexfvk)).
|
||||||
|
* Support async_deduplication_token for async insert. [#52136](https://github.com/ClickHouse/ClickHouse/pull/52136) ([Han Fei](https://github.com/hanfei1991)).
|
||||||
|
* Avro input format support Union with single type. Closes [#52131](https://github.com/ClickHouse/ClickHouse/issues/52131). [#52137](https://github.com/ClickHouse/ClickHouse/pull/52137) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Add setting `optimize_use_implicit_projections` to disable implicit projections (currently only `min_max_count` projection). This is defaulted to false until [#52075](https://github.com/ClickHouse/ClickHouse/issues/52075) is fixed. [#52152](https://github.com/ClickHouse/ClickHouse/pull/52152) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* It was possible to use the function `hasToken` for infinite loop. Now this possibility is removed. This closes [#52156](https://github.com/ClickHouse/ClickHouse/issues/52156). [#52160](https://github.com/ClickHouse/ClickHouse/pull/52160) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* 1. Upgrade Intel QPL from v1.1.0 to v1.2.0 2. Upgrade Intel accel-config from v3.5 to v4.0 3. Fixed issue that Device IOTLB miss has big perf. impact for IAA accelerators. [#52180](https://github.com/ClickHouse/ClickHouse/pull/52180) ([jasperzhu](https://github.com/jinjunzh)).
|
||||||
|
* Functions "date_diff() and age()" now support millisecond/microsecond unit and work with microsecond precision. [#52181](https://github.com/ClickHouse/ClickHouse/pull/52181) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Create ZK ancestors optimistically. [#52195](https://github.com/ClickHouse/ClickHouse/pull/52195) ([Raúl Marín](https://github.com/Algunenano)).
|
||||||
|
* Fix [#50582](https://github.com/ClickHouse/ClickHouse/issues/50582). Avoid the `Not found column ... in block` error in some cases of reading in-order and constants. [#52259](https://github.com/ClickHouse/ClickHouse/pull/52259) ([Chen768959](https://github.com/Chen768959)).
|
||||||
|
* Check whether S2 geo primitives are invalid as early as possible on ClickHouse side. This closes: [#27090](https://github.com/ClickHouse/ClickHouse/issues/27090). [#52260](https://github.com/ClickHouse/ClickHouse/pull/52260) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
|
||||||
|
* Now unquoted utf-8 strings are supported in DDL for MaterializedMySQL. [#52318](https://github.com/ClickHouse/ClickHouse/pull/52318) ([Val Doroshchuk](https://github.com/valbok)).
|
||||||
|
* Add back missing projection QueryAccessInfo when `query_plan_optimize_projection = 1`. This fixes [#50183](https://github.com/ClickHouse/ClickHouse/issues/50183) . This fixes [#50093](https://github.com/ClickHouse/ClickHouse/issues/50093) . [#52327](https://github.com/ClickHouse/ClickHouse/pull/52327) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* Add new setting `disable_url_encoding` that allows to disable decoding/encoding path in uri in URL engine. [#52337](https://github.com/ClickHouse/ClickHouse/pull/52337) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* When `ZooKeeperRetriesControl` rethrows an error, it's more useful to see its original stack trace, not the one from `ZooKeeperRetriesControl` itself. [#52347](https://github.com/ClickHouse/ClickHouse/pull/52347) ([Vitaly Baranov](https://github.com/vitlibar)).
|
||||||
|
* Now double quoted comments are supported in MaterializedMySQL. [#52355](https://github.com/ClickHouse/ClickHouse/pull/52355) ([Val Doroshchuk](https://github.com/valbok)).
|
||||||
|
* Wait for zero copy replication lock even if some disks don't support it. [#52376](https://github.com/ClickHouse/ClickHouse/pull/52376) ([Raúl Marín](https://github.com/Algunenano)).
|
||||||
|
* Now it's possible to specify min (`memory_profiler_sample_min_allocation_size`) and max (`memory_profiler_sample_max_allocation_size`) size for allocations to be tracked with sampling memory profiler. [#52419](https://github.com/ClickHouse/ClickHouse/pull/52419) ([alesapin](https://github.com/alesapin)).
|
||||||
|
* The `session_timezone` setting is demoted to experimental. [#52445](https://github.com/ClickHouse/ClickHouse/pull/52445) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Now interserver port will be closed only after tables are shut down. [#52498](https://github.com/ClickHouse/ClickHouse/pull/52498) ([alesapin](https://github.com/alesapin)).
|
||||||
|
* Added field `refcount` to `system.remote_data_paths` table. [#52518](https://github.com/ClickHouse/ClickHouse/pull/52518) ([Anton Popov](https://github.com/CurtizJ)).
|
||||||
|
* New setting `merge_tree_determine_task_size_by_prewhere_columns` added. If set to `true` only sizes of the columns from `PREWHERE` section will be considered to determine reading task size. Otherwise all the columns from query are considered. [#52606](https://github.com/ClickHouse/ClickHouse/pull/52606) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
|
||||||
|
#### Build/Testing/Packaging Improvement
|
||||||
|
* Add experimental ClickHouse builds for Linux RISC-V 64 to CI. [#31398](https://github.com/ClickHouse/ClickHouse/pull/31398) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fixed CRC32(WeakHash32) issue for s390x. [#50365](https://github.com/ClickHouse/ClickHouse/pull/50365) ([Harry Lee](https://github.com/HarryLeeIBM)).
|
||||||
|
* Add integration test check with the enabled analyzer. [#50926](https://github.com/ClickHouse/ClickHouse/pull/50926) ([Dmitry Novik](https://github.com/novikd)).
|
||||||
|
* Update cargo dependencies. [#51721](https://github.com/ClickHouse/ClickHouse/pull/51721) ([Raúl Marín](https://github.com/Algunenano)).
|
||||||
|
* Fixed several issues found by OSS-Fuzz. [#51736](https://github.com/ClickHouse/ClickHouse/pull/51736) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
|
||||||
|
* There were a couple of failures because of (?) S3 availability. The sccache has a feature of failing over to local compilation. [#51893](https://github.com/ClickHouse/ClickHouse/pull/51893) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
|
||||||
|
* 02242_delete_user_race and 02243_drop_user_grant_race tests have been corrected. [#51923](https://github.com/ClickHouse/ClickHouse/pull/51923) ([Alexey Gerasimchuck](https://github.com/Demilivor)).
|
||||||
|
* Make the function `CHColumnToArrowColumn::fillArrowArrayWithArrayColumnData` to work with nullable arrays, which are not possible in ClickHouse, but needed for Gluten. [#52112](https://github.com/ClickHouse/ClickHouse/pull/52112) ([李扬](https://github.com/taiyang-li)).
|
||||||
|
* We've updated the CCTZ library to master, but there are no user-visible changes. [#52124](https://github.com/ClickHouse/ClickHouse/pull/52124) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* The `system.licenses` table now includes the hard-forked library Poco. This closes [#52066](https://github.com/ClickHouse/ClickHouse/issues/52066). [#52127](https://github.com/ClickHouse/ClickHouse/pull/52127) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Follow up [#50926](https://github.com/ClickHouse/ClickHouse/issues/50926). Add integration tests check with enabled analyzer to master. [#52210](https://github.com/ClickHouse/ClickHouse/pull/52210) ([Dmitry Novik](https://github.com/novikd)).
|
||||||
|
* Reproducible builds for Rust. [#52395](https://github.com/ClickHouse/ClickHouse/pull/52395) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Improve the startup time of `clickhouse-client` and `clickhouse-local` in debug and sanitizer builds. This closes [#52228](https://github.com/ClickHouse/ClickHouse/issues/52228). [#52489](https://github.com/ClickHouse/ClickHouse/pull/52489) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Check that there are no cases of bad punctuation: whitespace before a comma like `Hello ,world` instead of `Hello, world`. [#52549](https://github.com/ClickHouse/ClickHouse/pull/52549) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
|
||||||
|
#### Bug Fix (user-visible misbehavior in an official stable release)
|
||||||
|
|
||||||
|
* Fix materialised pg syncTables [#49698](https://github.com/ClickHouse/ClickHouse/pull/49698) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Fix projection with optimize_aggregators_of_group_by_keys [#49709](https://github.com/ClickHouse/ClickHouse/pull/49709) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* Fix optimize_skip_unused_shards with JOINs [#51037](https://github.com/ClickHouse/ClickHouse/pull/51037) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix formatDateTime() with fractional negative datetime64 [#51290](https://github.com/ClickHouse/ClickHouse/pull/51290) ([Dmitry Kardymon](https://github.com/kardymonds)).
|
||||||
|
* Functions `hasToken*` were totally wrong. Add a test for [#43358](https://github.com/ClickHouse/ClickHouse/issues/43358) [#51378](https://github.com/ClickHouse/ClickHouse/pull/51378) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix optimization to move functions before sorting. [#51481](https://github.com/ClickHouse/ClickHouse/pull/51481) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||||
|
* Fix Block structure mismatch in Pipe::unitePipes for FINAL [#51492](https://github.com/ClickHouse/ClickHouse/pull/51492) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Fix SIGSEGV for clusters with zero weight across all shards (fixes INSERT INTO FUNCTION clusterAllReplicas()) [#51545](https://github.com/ClickHouse/ClickHouse/pull/51545) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix timeout for hedged requests [#51582](https://github.com/ClickHouse/ClickHouse/pull/51582) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix logical error in ANTI join with NULL [#51601](https://github.com/ClickHouse/ClickHouse/pull/51601) ([vdimir](https://github.com/vdimir)).
|
||||||
|
* Fix for moving 'IN' conditions to PREWHERE [#51610](https://github.com/ClickHouse/ClickHouse/pull/51610) ([Alexander Gololobov](https://github.com/davenger)).
|
||||||
|
* Do not apply PredicateExpressionsOptimizer for ASOF/ANTI join [#51633](https://github.com/ClickHouse/ClickHouse/pull/51633) ([vdimir](https://github.com/vdimir)).
|
||||||
|
* Fix async insert with deduplication for ReplicatedMergeTree using merging algorithms [#51676](https://github.com/ClickHouse/ClickHouse/pull/51676) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Fix reading from empty column in `parseSipHashKey` [#51804](https://github.com/ClickHouse/ClickHouse/pull/51804) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Fix segfault when create invalid EmbeddedRocksdb table [#51847](https://github.com/ClickHouse/ClickHouse/pull/51847) ([Duc Canh Le](https://github.com/canhld94)).
|
||||||
|
* Fix inserts into MongoDB tables [#51876](https://github.com/ClickHouse/ClickHouse/pull/51876) ([Nikolay Degterinsky](https://github.com/evillique)).
|
||||||
|
* Fix deadlock on DatabaseCatalog shutdown [#51908](https://github.com/ClickHouse/ClickHouse/pull/51908) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Fix error in subquery operators [#51922](https://github.com/ClickHouse/ClickHouse/pull/51922) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix async connect to hosts with multiple ips [#51934](https://github.com/ClickHouse/ClickHouse/pull/51934) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Do not remove inputs after ActionsDAG::merge [#51947](https://github.com/ClickHouse/ClickHouse/pull/51947) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||||
|
* Check refcount in `RemoveManyObjectStorageOperation::finalize` instead of `execute` [#51954](https://github.com/ClickHouse/ClickHouse/pull/51954) ([vdimir](https://github.com/vdimir)).
|
||||||
|
* Allow parametric UDFs [#51964](https://github.com/ClickHouse/ClickHouse/pull/51964) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Small fix for toDateTime64() for dates after 2283-12-31 [#52130](https://github.com/ClickHouse/ClickHouse/pull/52130) ([Andrey Zvonov](https://github.com/zvonand)).
|
||||||
|
* Fix ORDER BY tuple of WINDOW functions [#52145](https://github.com/ClickHouse/ClickHouse/pull/52145) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix incorrect projection analysis when aggregation expression contains monotonic functions [#52151](https://github.com/ClickHouse/ClickHouse/pull/52151) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* Fix error in `groupArrayMoving` functions [#52161](https://github.com/ClickHouse/ClickHouse/pull/52161) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Disable direct join for range dictionary [#52187](https://github.com/ClickHouse/ClickHouse/pull/52187) ([Duc Canh Le](https://github.com/canhld94)).
|
||||||
|
* Fix sticky mutations test (and extremely rare race condition) [#52197](https://github.com/ClickHouse/ClickHouse/pull/52197) ([alesapin](https://github.com/alesapin)).
|
||||||
|
* Fix race in Web disk [#52211](https://github.com/ClickHouse/ClickHouse/pull/52211) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Fix data race in Connection::setAsyncCallback on unknown packet from server [#52219](https://github.com/ClickHouse/ClickHouse/pull/52219) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Fix temp data deletion on startup, add test [#52275](https://github.com/ClickHouse/ClickHouse/pull/52275) ([vdimir](https://github.com/vdimir)).
|
||||||
|
* Don't use minmax_count projections when counting nullable columns [#52297](https://github.com/ClickHouse/ClickHouse/pull/52297) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* MergeTree/ReplicatedMergeTree should use server timezone for log entries [#52325](https://github.com/ClickHouse/ClickHouse/pull/52325) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix parameterized view with cte and multiple usage [#52328](https://github.com/ClickHouse/ClickHouse/pull/52328) ([SmitaRKulkarni](https://github.com/SmitaRKulkarni)).
|
||||||
|
* Disable expression templates for time intervals [#52335](https://github.com/ClickHouse/ClickHouse/pull/52335) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Fix `apply_snapshot` in Keeper [#52358](https://github.com/ClickHouse/ClickHouse/pull/52358) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Update build-osx.md [#52377](https://github.com/ClickHouse/ClickHouse/pull/52377) ([AlexBykovski](https://github.com/AlexBykovski)).
|
||||||
|
* Fix `countSubstrings()` hang with empty needle and a column haystack [#52409](https://github.com/ClickHouse/ClickHouse/pull/52409) ([Sergei Trifonov](https://github.com/serxa)).
|
||||||
|
* Fix normal projection with merge table [#52432](https://github.com/ClickHouse/ClickHouse/pull/52432) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* Fix possible double-free in Aggregator [#52439](https://github.com/ClickHouse/ClickHouse/pull/52439) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Fixed inserting into Buffer engine [#52440](https://github.com/ClickHouse/ClickHouse/pull/52440) ([Vasily Nemkov](https://github.com/Enmk)).
|
||||||
|
* The implementation of AnyHash was non-conformant. [#52448](https://github.com/ClickHouse/ClickHouse/pull/52448) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Check recursion depth in OptimizedRegularExpression [#52451](https://github.com/ClickHouse/ClickHouse/pull/52451) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix data-race DatabaseReplicated::startupTables()/canExecuteReplicatedMetadataAlter() [#52490](https://github.com/ClickHouse/ClickHouse/pull/52490) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix abort in function `transform` [#52513](https://github.com/ClickHouse/ClickHouse/pull/52513) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix lightweight delete after drop of projection [#52517](https://github.com/ClickHouse/ClickHouse/pull/52517) ([Anton Popov](https://github.com/CurtizJ)).
|
||||||
|
* Fix possible error "Cannot drain connections: cancel first" [#52585](https://github.com/ClickHouse/ClickHouse/pull/52585) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
|
||||||
|
#### NO CL ENTRY
|
||||||
|
|
||||||
|
* NO CL ENTRY: 'Revert "Add documentation for building in docker"'. [#51773](https://github.com/ClickHouse/ClickHouse/pull/51773) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* NO CL ENTRY: 'Revert "Fix build"'. [#51911](https://github.com/ClickHouse/ClickHouse/pull/51911) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* NO CL ENTRY: 'Revert "Millisecond and microsecond support in date_diff / age functions"'. [#52129](https://github.com/ClickHouse/ClickHouse/pull/52129) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* NO CL ENTRY: 'Revert "Re-add SipHash keyed functions"'. [#52466](https://github.com/ClickHouse/ClickHouse/pull/52466) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* NO CL ENTRY: 'Revert "Add an ability to specify allocations size for sampling memory profiler"'. [#52496](https://github.com/ClickHouse/ClickHouse/pull/52496) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* NO CL ENTRY: 'Revert "Rewrite uniq to count"'. [#52576](https://github.com/ClickHouse/ClickHouse/pull/52576) ([Yarik Briukhovetskyi](https://github.com/yariks5s)).
|
||||||
|
|
||||||
|
#### NOT FOR CHANGELOG / INSIGNIFICANT
|
||||||
|
|
||||||
|
* Remove duplicate_order_by_and_distinct optimization [#47135](https://github.com/ClickHouse/ClickHouse/pull/47135) ([Igor Nikonov](https://github.com/devcrafter)).
|
||||||
|
* Update sort desc in ReadFromMergeTree after applying PREWHERE info [#48669](https://github.com/ClickHouse/ClickHouse/pull/48669) ([Igor Nikonov](https://github.com/devcrafter)).
|
||||||
|
* Fix `BindException: Address already in use` in HDFS integration tests [#49428](https://github.com/ClickHouse/ClickHouse/pull/49428) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Force libunwind usage (removes gcc_eh support) [#49438](https://github.com/ClickHouse/ClickHouse/pull/49438) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Cleanup `storage_conf.xml` [#49557](https://github.com/ClickHouse/ClickHouse/pull/49557) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Fix flaky tests caused by OPTIMIZE FINAL failing memory budget check [#49764](https://github.com/ClickHouse/ClickHouse/pull/49764) ([Michael Kolupaev](https://github.com/al13n321)).
|
||||||
|
* Remove unstable queries from performance/join_set_filter [#50235](https://github.com/ClickHouse/ClickHouse/pull/50235) ([vdimir](https://github.com/vdimir)).
|
||||||
|
* More accurate DNS resolve for the keeper connection [#50738](https://github.com/ClickHouse/ClickHouse/pull/50738) ([pufit](https://github.com/pufit)).
|
||||||
|
* Try to fix some trash in Disks and part moves [#51135](https://github.com/ClickHouse/ClickHouse/pull/51135) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Add jemalloc support fro s390x [#51186](https://github.com/ClickHouse/ClickHouse/pull/51186) ([Boris Kuschel](https://github.com/bkuschel)).
|
||||||
|
* Resubmit [#48821](https://github.com/ClickHouse/ClickHouse/issues/48821) [#51208](https://github.com/ClickHouse/ClickHouse/pull/51208) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* test for [#36894](https://github.com/ClickHouse/ClickHouse/issues/36894) [#51274](https://github.com/ClickHouse/ClickHouse/pull/51274) ([Denny Crane](https://github.com/den-crane)).
|
||||||
|
* external_aggregation_fix for big endian machines [#51280](https://github.com/ClickHouse/ClickHouse/pull/51280) ([Sanjam Panda](https://github.com/saitama951)).
|
||||||
|
* Fix: Invalid number of rows in Chunk column Object [#51296](https://github.com/ClickHouse/ClickHouse/pull/51296) ([Igor Nikonov](https://github.com/devcrafter)).
|
||||||
|
* Add a test for [#44816](https://github.com/ClickHouse/ClickHouse/issues/44816) [#51305](https://github.com/ClickHouse/ClickHouse/pull/51305) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Add a test for `calculate_text_stack_trace` setting [#51311](https://github.com/ClickHouse/ClickHouse/pull/51311) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* decrease log level, make logs shorter [#51320](https://github.com/ClickHouse/ClickHouse/pull/51320) ([Sema Checherinda](https://github.com/CheSema)).
|
||||||
|
* Collect stack traces from job's scheduling and print along with exception's stack trace. [#51349](https://github.com/ClickHouse/ClickHouse/pull/51349) ([Yakov Olkhovskiy](https://github.com/yakov-olkhovskiy)).
|
||||||
|
* Add a test for [#42691](https://github.com/ClickHouse/ClickHouse/issues/42691) [#51352](https://github.com/ClickHouse/ClickHouse/pull/51352) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Add a test for [#32474](https://github.com/ClickHouse/ClickHouse/issues/32474) [#51354](https://github.com/ClickHouse/ClickHouse/pull/51354) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Add a test for [#41727](https://github.com/ClickHouse/ClickHouse/issues/41727) [#51355](https://github.com/ClickHouse/ClickHouse/pull/51355) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Add a test for [#35801](https://github.com/ClickHouse/ClickHouse/issues/35801) [#51356](https://github.com/ClickHouse/ClickHouse/pull/51356) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Add a test for [#34626](https://github.com/ClickHouse/ClickHouse/issues/34626) [#51357](https://github.com/ClickHouse/ClickHouse/pull/51357) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Initialize text_log earlier to capture table startup messages [#51360](https://github.com/ClickHouse/ClickHouse/pull/51360) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Use separate default settings for clickhouse-local [#51363](https://github.com/ClickHouse/ClickHouse/pull/51363) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Attempt to remove wrong code (catch/throw in Functions) [#51367](https://github.com/ClickHouse/ClickHouse/pull/51367) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Remove suspicious code [#51383](https://github.com/ClickHouse/ClickHouse/pull/51383) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Disable hedged requests under TSan [#51392](https://github.com/ClickHouse/ClickHouse/pull/51392) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* no finalize in d-tor WriteBufferFromOStream [#51404](https://github.com/ClickHouse/ClickHouse/pull/51404) ([Sema Checherinda](https://github.com/CheSema)).
|
||||||
|
* Better diagnostics for 01193_metadata_loading [#51414](https://github.com/ClickHouse/ClickHouse/pull/51414) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Fix attaching gdb in stress tests [#51445](https://github.com/ClickHouse/ClickHouse/pull/51445) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Merging [#36384](https://github.com/ClickHouse/ClickHouse/issues/36384) [#51458](https://github.com/ClickHouse/ClickHouse/pull/51458) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix possible race on shutdown wait [#51497](https://github.com/ClickHouse/ClickHouse/pull/51497) ([Sergei Trifonov](https://github.com/serxa)).
|
||||||
|
* Fix `test_alter_moving_garbage`: lock between getActiveContainingPart and swapActivePart in parts mover [#51498](https://github.com/ClickHouse/ClickHouse/pull/51498) ([vdimir](https://github.com/vdimir)).
|
||||||
|
* Fix a logical error on mutation [#51502](https://github.com/ClickHouse/ClickHouse/pull/51502) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Fix running integration tests with spaces in it's names [#51514](https://github.com/ClickHouse/ClickHouse/pull/51514) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix flaky test 00417_kill_query [#51522](https://github.com/ClickHouse/ClickHouse/pull/51522) ([Nikolay Degterinsky](https://github.com/evillique)).
|
||||||
|
* fs cache: add some checks [#51536](https://github.com/ClickHouse/ClickHouse/pull/51536) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Don't run 02782_uniq_exact_parallel_merging_bug in parallel with other tests [#51549](https://github.com/ClickHouse/ClickHouse/pull/51549) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* 00900_orc_load: lift kill timeout [#51559](https://github.com/ClickHouse/ClickHouse/pull/51559) ([Robert Schulze](https://github.com/rschu1ze)).
|
||||||
|
* Add retries to 00416_pocopatch_progress_in_http_headers [#51575](https://github.com/ClickHouse/ClickHouse/pull/51575) ([Nikolay Degterinsky](https://github.com/evillique)).
|
||||||
|
* Remove the usage of Analyzer setting in the client [#51578](https://github.com/ClickHouse/ClickHouse/pull/51578) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix merge_selecting_task scheduling [#51591](https://github.com/ClickHouse/ClickHouse/pull/51591) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Add hex functions for cityhash [#51595](https://github.com/ClickHouse/ClickHouse/pull/51595) ([Vitaly Baranov](https://github.com/vitlibar)).
|
||||||
|
* Remove `unset CLICKHOUSE_LOG_COMMENT` from tests [#51623](https://github.com/ClickHouse/ClickHouse/pull/51623) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Implement endianness-independent serialization [#51637](https://github.com/ClickHouse/ClickHouse/pull/51637) ([ltrk2](https://github.com/ltrk2)).
|
||||||
|
* Ignore APPEND and TRUNCATE modifiers if file does not exist. [#51640](https://github.com/ClickHouse/ClickHouse/pull/51640) ([alekar](https://github.com/alekar)).
|
||||||
|
* Try to fix flaky 02210_processors_profile_log [#51641](https://github.com/ClickHouse/ClickHouse/pull/51641) ([Igor Nikonov](https://github.com/devcrafter)).
|
||||||
|
* Make common macros extendable [#51646](https://github.com/ClickHouse/ClickHouse/pull/51646) ([Amos Bird](https://github.com/amosbird)).
|
||||||
|
* Correct an exception message in src/Functions/nested.cpp [#51651](https://github.com/ClickHouse/ClickHouse/pull/51651) ([Alex Cheng](https://github.com/Alex-Cheng)).
|
||||||
|
* tests: fix 02050_client_profile_events flakiness [#51653](https://github.com/ClickHouse/ClickHouse/pull/51653) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Minor follow-up to re2 update to 2023-06-02 ([#50949](https://github.com/ClickHouse/ClickHouse/issues/50949)) [#51655](https://github.com/ClickHouse/ClickHouse/pull/51655) ([Robert Schulze](https://github.com/rschu1ze)).
|
||||||
|
* Fix 02116_tuple_element with Analyzer [#51669](https://github.com/ClickHouse/ClickHouse/pull/51669) ([Robert Schulze](https://github.com/rschu1ze)).
|
||||||
|
* Update timeouts in tests for transactions [#51683](https://github.com/ClickHouse/ClickHouse/pull/51683) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Remove unused code [#51684](https://github.com/ClickHouse/ClickHouse/pull/51684) ([Sergei Trifonov](https://github.com/serxa)).
|
||||||
|
* Remove `mmap/mremap/munmap` from Allocator.h [#51686](https://github.com/ClickHouse/ClickHouse/pull/51686) ([alesapin](https://github.com/alesapin)).
|
||||||
|
* SonarCloud: Add C++23 Experimental Flag [#51687](https://github.com/ClickHouse/ClickHouse/pull/51687) ([Julio Jimenez](https://github.com/juliojimenez)).
|
||||||
|
* Wait with retries when attaching GDB in tests [#51688](https://github.com/ClickHouse/ClickHouse/pull/51688) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Update version_date.tsv and changelogs after v23.6.1.1524-stable [#51691](https://github.com/ClickHouse/ClickHouse/pull/51691) ([robot-clickhouse](https://github.com/robot-clickhouse)).
|
||||||
|
* fix write to finalized buffer [#51696](https://github.com/ClickHouse/ClickHouse/pull/51696) ([Sema Checherinda](https://github.com/CheSema)).
|
||||||
|
* do not log exception aborted for pending mutate/merge entries when shutdown [#51697](https://github.com/ClickHouse/ClickHouse/pull/51697) ([Sema Checherinda](https://github.com/CheSema)).
|
||||||
|
* Fix race in ContextAccess [#51704](https://github.com/ClickHouse/ClickHouse/pull/51704) ([Vitaly Baranov](https://github.com/vitlibar)).
|
||||||
|
* Make test scripts backwards compatible [#51707](https://github.com/ClickHouse/ClickHouse/pull/51707) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* test for full join and null predicate [#51709](https://github.com/ClickHouse/ClickHouse/pull/51709) ([Denny Crane](https://github.com/den-crane)).
|
||||||
|
* A cmake warning on job limits underutilizing CPU [#51710](https://github.com/ClickHouse/ClickHouse/pull/51710) ([velavokr](https://github.com/velavokr)).
|
||||||
|
* Fix SQLLogic docker images [#51719](https://github.com/ClickHouse/ClickHouse/pull/51719) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Added ASK_PASSWORD client constant instead of hardcoded '\n' [#51723](https://github.com/ClickHouse/ClickHouse/pull/51723) ([Alexey Gerasimchuck](https://github.com/Demilivor)).
|
||||||
|
* Update README.md [#51726](https://github.com/ClickHouse/ClickHouse/pull/51726) ([Tyler Hannan](https://github.com/tylerhannan)).
|
||||||
|
* Fix source image for sqllogic [#51728](https://github.com/ClickHouse/ClickHouse/pull/51728) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
|
||||||
|
* Remove MemoryPool from Poco because it's useless [#51732](https://github.com/ClickHouse/ClickHouse/pull/51732) ([alesapin](https://github.com/alesapin)).
|
||||||
|
* Fix: logical error in grace hash join [#51737](https://github.com/ClickHouse/ClickHouse/pull/51737) ([Igor Nikonov](https://github.com/devcrafter)).
|
||||||
|
* Update 01320_create_sync_race_condition_zookeeper.sh [#51742](https://github.com/ClickHouse/ClickHouse/pull/51742) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Pin for docker-ce [#51743](https://github.com/ClickHouse/ClickHouse/pull/51743) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
|
||||||
|
* Revert "Fix: Invalid number of rows in Chunk column Object" [#51750](https://github.com/ClickHouse/ClickHouse/pull/51750) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Add SonarCloud to README [#51751](https://github.com/ClickHouse/ClickHouse/pull/51751) ([Robert Schulze](https://github.com/rschu1ze)).
|
||||||
|
* Fix test `02789_object_type_invalid_num_of_rows` [#51754](https://github.com/ClickHouse/ClickHouse/pull/51754) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix (benign) data race in `transform` [#51755](https://github.com/ClickHouse/ClickHouse/pull/51755) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix flaky KeeperMap test [#51764](https://github.com/ClickHouse/ClickHouse/pull/51764) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Version mypy=1.4.1 falsly reports unused ignore comment [#51769](https://github.com/ClickHouse/ClickHouse/pull/51769) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
|
||||||
|
* Avoid keeping lock Context::getLock() while calculating access rights [#51772](https://github.com/ClickHouse/ClickHouse/pull/51772) ([Vitaly Baranov](https://github.com/vitlibar)).
|
||||||
|
* Making stateless tests with timeout less flaky [#51774](https://github.com/ClickHouse/ClickHouse/pull/51774) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Fix after [#51000](https://github.com/ClickHouse/ClickHouse/issues/51000) [#51790](https://github.com/ClickHouse/ClickHouse/pull/51790) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Add assert in ThreadStatus destructor for correct current_thread [#51800](https://github.com/ClickHouse/ClickHouse/pull/51800) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Fix broken parts handling in `ReplicatedMergeTree` [#51801](https://github.com/ClickHouse/ClickHouse/pull/51801) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Fix tsan signal-unsafe call [#51802](https://github.com/ClickHouse/ClickHouse/pull/51802) ([Yakov Olkhovskiy](https://github.com/yakov-olkhovskiy)).
|
||||||
|
* Fix for parallel replicas not completely disabled by granule count threshold [#51805](https://github.com/ClickHouse/ClickHouse/pull/51805) ([Alexander Gololobov](https://github.com/davenger)).
|
||||||
|
* Make sure that we don't attempt to serialize/deserialize block with 0 columns and non-zero rows [#51807](https://github.com/ClickHouse/ClickHouse/pull/51807) ([Alexander Gololobov](https://github.com/davenger)).
|
||||||
|
* Fix rare bug in `DROP COLUMN` and enabled sparse columns [#51809](https://github.com/ClickHouse/ClickHouse/pull/51809) ([Anton Popov](https://github.com/CurtizJ)).
|
||||||
|
* Fix flaky `test_multiple_disks` [#51821](https://github.com/ClickHouse/ClickHouse/pull/51821) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Follow up to [#51547](https://github.com/ClickHouse/ClickHouse/issues/51547) [#51822](https://github.com/ClickHouse/ClickHouse/pull/51822) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Correctly grep archives in stress tests [#51824](https://github.com/ClickHouse/ClickHouse/pull/51824) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Update analyzer_tech_debt.txt [#51836](https://github.com/ClickHouse/ClickHouse/pull/51836) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* remove unused code [#51837](https://github.com/ClickHouse/ClickHouse/pull/51837) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Fix disk config for upgrade tests [#51839](https://github.com/ClickHouse/ClickHouse/pull/51839) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Remove Coverity from workflows, but leave in the code [#51842](https://github.com/ClickHouse/ClickHouse/pull/51842) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Many fixes [3] [#51848](https://github.com/ClickHouse/ClickHouse/pull/51848) ([Ilya Yatsishin](https://github.com/qoega)).
|
||||||
|
* Change misleading name in joins: addJoinedBlock -> addBlockToJoin [#51852](https://github.com/ClickHouse/ClickHouse/pull/51852) ([Igor Nikonov](https://github.com/devcrafter)).
|
||||||
|
* fix: correct exception messages on policies comparison [#51854](https://github.com/ClickHouse/ClickHouse/pull/51854) ([Feng Kaiyu](https://github.com/fky2015)).
|
||||||
|
* Update 02439_merge_selecting_partitions.sql [#51862](https://github.com/ClickHouse/ClickHouse/pull/51862) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Remove useless packages [#51863](https://github.com/ClickHouse/ClickHouse/pull/51863) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Remove useless logs [#51865](https://github.com/ClickHouse/ClickHouse/pull/51865) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix incorrect log level = warning [#51867](https://github.com/ClickHouse/ClickHouse/pull/51867) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix test_replicated_table_attach [#51868](https://github.com/ClickHouse/ClickHouse/pull/51868) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Better usability of a test [#51869](https://github.com/ClickHouse/ClickHouse/pull/51869) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Remove useless code [#51873](https://github.com/ClickHouse/ClickHouse/pull/51873) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Another fix upgrade check script [#51878](https://github.com/ClickHouse/ClickHouse/pull/51878) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Sqlloogic improvements [#51883](https://github.com/ClickHouse/ClickHouse/pull/51883) ([Ilya Yatsishin](https://github.com/qoega)).
|
||||||
|
* Disable ThinLTO on non-Linux [#51897](https://github.com/ClickHouse/ClickHouse/pull/51897) ([Robert Schulze](https://github.com/rschu1ze)).
|
||||||
|
* Pin rust nightly (to make it stable) [#51903](https://github.com/ClickHouse/ClickHouse/pull/51903) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix build [#51909](https://github.com/ClickHouse/ClickHouse/pull/51909) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix build [#51910](https://github.com/ClickHouse/ClickHouse/pull/51910) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix flaky test `00175_partition_by_ignore` and move it to correct location [#51913](https://github.com/ClickHouse/ClickHouse/pull/51913) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix flaky test 02360_send_logs_level_colors: avoid usage of `file` tool [#51914](https://github.com/ClickHouse/ClickHouse/pull/51914) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Maybe better tests [#51916](https://github.com/ClickHouse/ClickHouse/pull/51916) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Revert system drop filesystem cache by key [#51917](https://github.com/ClickHouse/ClickHouse/pull/51917) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix flaky test `detach_attach_partition_race` [#51920](https://github.com/ClickHouse/ClickHouse/pull/51920) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Another fix for `02481_async_insert_race_long` [#51925](https://github.com/ClickHouse/ClickHouse/pull/51925) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Fix segfault caused by `ThreadStatus` [#51931](https://github.com/ClickHouse/ClickHouse/pull/51931) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Print short fault info only from safe fields [#51932](https://github.com/ClickHouse/ClickHouse/pull/51932) ([Alexander Gololobov](https://github.com/davenger)).
|
||||||
|
* Fix typo in integration tests [#51944](https://github.com/ClickHouse/ClickHouse/pull/51944) ([Ilya Yatsishin](https://github.com/qoega)).
|
||||||
|
* Better logs on shutdown [#51951](https://github.com/ClickHouse/ClickHouse/pull/51951) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Filter databases list before querying potentially slow fields [#51955](https://github.com/ClickHouse/ClickHouse/pull/51955) ([Alexander Gololobov](https://github.com/davenger)).
|
||||||
|
* Fix some issues with transactions [#51959](https://github.com/ClickHouse/ClickHouse/pull/51959) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Fix unrelated messages from LSan in clickhouse-client [#51966](https://github.com/ClickHouse/ClickHouse/pull/51966) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Allow OOM in AST Fuzzer with Sanitizers [#51967](https://github.com/ClickHouse/ClickHouse/pull/51967) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Disable one test under Analyzer [#51968](https://github.com/ClickHouse/ClickHouse/pull/51968) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix Docker [#51969](https://github.com/ClickHouse/ClickHouse/pull/51969) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix test `01825_type_json_from_map` [#51970](https://github.com/ClickHouse/ClickHouse/pull/51970) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix test `02354_distributed_with_external_aggregation_memory_usage` [#51971](https://github.com/ClickHouse/ClickHouse/pull/51971) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix disaster in integration tests, part 2 [#51973](https://github.com/ClickHouse/ClickHouse/pull/51973) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* [RFC] Cleanup remote_servers in dist config.xml [#51985](https://github.com/ClickHouse/ClickHouse/pull/51985) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Update version_date.tsv and changelogs after v23.6.2.18-stable [#51986](https://github.com/ClickHouse/ClickHouse/pull/51986) ([robot-clickhouse](https://github.com/robot-clickhouse)).
|
||||||
|
* Update version_date.tsv and changelogs after v22.8.20.11-lts [#51987](https://github.com/ClickHouse/ClickHouse/pull/51987) ([robot-clickhouse](https://github.com/robot-clickhouse)).
|
||||||
|
* Fix performance test for regexp cache [#51988](https://github.com/ClickHouse/ClickHouse/pull/51988) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Move a test to the right place [#51989](https://github.com/ClickHouse/ClickHouse/pull/51989) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Add a check to validate that the stateful tests are stateful [#51990](https://github.com/ClickHouse/ClickHouse/pull/51990) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Check that functional tests cleanup their tables [#51991](https://github.com/ClickHouse/ClickHouse/pull/51991) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix test_extreme_deduplication [#51992](https://github.com/ClickHouse/ClickHouse/pull/51992) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Cleanup SymbolIndex after reload got removed [#51993](https://github.com/ClickHouse/ClickHouse/pull/51993) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Update CompletedPipelineExecutor exception log name [#52028](https://github.com/ClickHouse/ClickHouse/pull/52028) ([xiao](https://github.com/nicelulu)).
|
||||||
|
* Fix `00502_custom_partitioning_replicated_zookeeper_long` [#52032](https://github.com/ClickHouse/ClickHouse/pull/52032) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Prohibit send_metadata for s3_plain disks [#52038](https://github.com/ClickHouse/ClickHouse/pull/52038) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Update version_date.tsv and changelogs after v23.4.6.25-stable [#52061](https://github.com/ClickHouse/ClickHouse/pull/52061) ([robot-clickhouse](https://github.com/robot-clickhouse)).
|
||||||
|
* Preparations for Trivial Support For Resharding (part1) [#52068](https://github.com/ClickHouse/ClickHouse/pull/52068) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Update version_date.tsv and changelogs after v23.3.8.21-lts [#52077](https://github.com/ClickHouse/ClickHouse/pull/52077) ([robot-clickhouse](https://github.com/robot-clickhouse)).
|
||||||
|
* Fix flakiness of test_keeper_s3_snapshot flakiness [#52083](https://github.com/ClickHouse/ClickHouse/pull/52083) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix test_extreme_deduplication flakiness [#52085](https://github.com/ClickHouse/ClickHouse/pull/52085) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Small docs update for toYearWeek() function [#52090](https://github.com/ClickHouse/ClickHouse/pull/52090) ([Andrey Zvonov](https://github.com/zvonand)).
|
||||||
|
* Small docs update for DateTime, DateTime64 [#52094](https://github.com/ClickHouse/ClickHouse/pull/52094) ([Andrey Zvonov](https://github.com/zvonand)).
|
||||||
|
* Add missing --force for docker network prune (otherwise it is noop on CI) [#52095](https://github.com/ClickHouse/ClickHouse/pull/52095) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* tests: drop existing view in test_materialized_mysql_database [#52103](https://github.com/ClickHouse/ClickHouse/pull/52103) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Update README.md [#52115](https://github.com/ClickHouse/ClickHouse/pull/52115) ([Tyler Hannan](https://github.com/tylerhannan)).
|
||||||
|
* Print Zxid in keeper stat command in hex (so as ZooKeeper) [#52122](https://github.com/ClickHouse/ClickHouse/pull/52122) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Skip protection from double decompression if inode from maps cannot be obtained [#52138](https://github.com/ClickHouse/ClickHouse/pull/52138) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* There is no point in detecting flaky tests [#52142](https://github.com/ClickHouse/ClickHouse/pull/52142) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Remove default argument value [#52143](https://github.com/ClickHouse/ClickHouse/pull/52143) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix the "kill_mutation" test [#52144](https://github.com/ClickHouse/ClickHouse/pull/52144) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix ORDER BY tuple of WINDOW functions (and slightly more changes) [#52146](https://github.com/ClickHouse/ClickHouse/pull/52146) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix possible EADDRINUSE ("Address already in use") in integration tests [#52148](https://github.com/ClickHouse/ClickHouse/pull/52148) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix test 02497_storage_file_reader_selection [#52154](https://github.com/ClickHouse/ClickHouse/pull/52154) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix unexpected AST Set [#52158](https://github.com/ClickHouse/ClickHouse/pull/52158) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix crash in comparison functions due to incorrect query analysis [#52172](https://github.com/ClickHouse/ClickHouse/pull/52172) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix slow test `02317_distinct_in_order_optimization` [#52173](https://github.com/ClickHouse/ClickHouse/pull/52173) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Add comments for https://github.com/ClickHouse/ClickHouse/pull/52112 [#52175](https://github.com/ClickHouse/ClickHouse/pull/52175) ([李扬](https://github.com/taiyang-li)).
|
||||||
|
* Randomize timezone in tests across non-deterministic around 1970 and default [#52184](https://github.com/ClickHouse/ClickHouse/pull/52184) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix `test_multiple_disks/test.py::test_start_stop_moves` [#52189](https://github.com/ClickHouse/ClickHouse/pull/52189) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* CMake: Simplify job limiting [#52196](https://github.com/ClickHouse/ClickHouse/pull/52196) ([Robert Schulze](https://github.com/rschu1ze)).
|
||||||
|
* Fix self extracting binaries under qemu linux-user (qemu-$ARCH-static) [#52198](https://github.com/ClickHouse/ClickHouse/pull/52198) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix `Integration tests flaky check (asan)` [#52201](https://github.com/ClickHouse/ClickHouse/pull/52201) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Fix flaky test test_lost_part [#52202](https://github.com/ClickHouse/ClickHouse/pull/52202) ([alesapin](https://github.com/alesapin)).
|
||||||
|
* MaterializedMySQL: Replace to_string by magic_enum::enum_name [#52204](https://github.com/ClickHouse/ClickHouse/pull/52204) ([Val Doroshchuk](https://github.com/valbok)).
|
||||||
|
* MaterializedMySQL: Add tests to parse db and table names from DDL [#52208](https://github.com/ClickHouse/ClickHouse/pull/52208) ([Val Doroshchuk](https://github.com/valbok)).
|
||||||
|
* Revert "Fixed several issues found by OSS-Fuzz" [#52216](https://github.com/ClickHouse/ClickHouse/pull/52216) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
|
||||||
|
* Use one copy replication more agressively [#52218](https://github.com/ClickHouse/ClickHouse/pull/52218) ([alesapin](https://github.com/alesapin)).
|
||||||
|
* Fix flaky test `01076_parallel_alter_replicated_zookeeper` [#52221](https://github.com/ClickHouse/ClickHouse/pull/52221) ([alesapin](https://github.com/alesapin)).
|
||||||
|
* Fix 01889_key_condition_function_chains for analyzer. [#52223](https://github.com/ClickHouse/ClickHouse/pull/52223) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||||
|
* Inhibit settings randomization in the test `json_ghdata` [#52226](https://github.com/ClickHouse/ClickHouse/pull/52226) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Slightly better diagnostics in a test [#52227](https://github.com/ClickHouse/ClickHouse/pull/52227) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Enable no-upgrade-check for 02273_full_sort_join [#52235](https://github.com/ClickHouse/ClickHouse/pull/52235) ([vdimir](https://github.com/vdimir)).
|
||||||
|
* Fix network manager for integration tests [#52237](https://github.com/ClickHouse/ClickHouse/pull/52237) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* List replication queue only for current test database [#52238](https://github.com/ClickHouse/ClickHouse/pull/52238) ([Alexander Gololobov](https://github.com/davenger)).
|
||||||
|
* Attempt to fix assert in tsan with fibers [#52241](https://github.com/ClickHouse/ClickHouse/pull/52241) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Fix undefined behaviour in fuzzer [#52256](https://github.com/ClickHouse/ClickHouse/pull/52256) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Follow-up to [#51959](https://github.com/ClickHouse/ClickHouse/issues/51959) [#52261](https://github.com/ClickHouse/ClickHouse/pull/52261) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* More fair queue for `drop table sync` [#52276](https://github.com/ClickHouse/ClickHouse/pull/52276) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Fix `02497_trace_events_stress_long` [#52279](https://github.com/ClickHouse/ClickHouse/pull/52279) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Fix test `01111_create_drop_replicated_db_stress` [#52283](https://github.com/ClickHouse/ClickHouse/pull/52283) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Fix ugly code [#52284](https://github.com/ClickHouse/ClickHouse/pull/52284) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* Add missing replica syncs in test_backup_restore_on_cluster [#52306](https://github.com/ClickHouse/ClickHouse/pull/52306) ([Michael Kolupaev](https://github.com/al13n321)).
|
||||||
|
* Fix test_replicated_database 'node doesn't exist' flakiness [#52307](https://github.com/ClickHouse/ClickHouse/pull/52307) ([Michael Kolupaev](https://github.com/al13n321)).
|
||||||
|
* Minor: Update description of events "QueryCacheHits/Misses" [#52309](https://github.com/ClickHouse/ClickHouse/pull/52309) ([Robert Schulze](https://github.com/rschu1ze)).
|
||||||
|
* Beautify pretty-printing of the query string in SYSTEM.QUERY_CACHE [#52312](https://github.com/ClickHouse/ClickHouse/pull/52312) ([Robert Schulze](https://github.com/rschu1ze)).
|
||||||
|
* Reduce dependencies for skim by avoid using default features [#52316](https://github.com/ClickHouse/ClickHouse/pull/52316) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix 02725_memory-for-merges [#52317](https://github.com/ClickHouse/ClickHouse/pull/52317) ([alesapin](https://github.com/alesapin)).
|
||||||
|
* Skip unsupported disks in Keeper [#52321](https://github.com/ClickHouse/ClickHouse/pull/52321) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Revert "Improve CSVInputFormat to check and set default value to column if deserialize failed" [#52322](https://github.com/ClickHouse/ClickHouse/pull/52322) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Resubmit [#51716](https://github.com/ClickHouse/ClickHouse/issues/51716) [#52323](https://github.com/ClickHouse/ClickHouse/pull/52323) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Add logging about all found workflows for merge_pr.py [#52324](https://github.com/ClickHouse/ClickHouse/pull/52324) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
|
||||||
|
* Minor: Less awkward IAST::FormatSettings [#52332](https://github.com/ClickHouse/ClickHouse/pull/52332) ([Robert Schulze](https://github.com/rschu1ze)).
|
||||||
|
* Mark test 02125_many_mutations_2 as no-parallel to avoid flakiness [#52338](https://github.com/ClickHouse/ClickHouse/pull/52338) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Fix capabilities installed via systemd service (fixes netlink/IO priorities) [#52357](https://github.com/ClickHouse/ClickHouse/pull/52357) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Update 01606_git_import.sh [#52360](https://github.com/ClickHouse/ClickHouse/pull/52360) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Update ci-slack-bot.py [#52372](https://github.com/ClickHouse/ClickHouse/pull/52372) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Fix `test_keeper_session` [#52373](https://github.com/ClickHouse/ClickHouse/pull/52373) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Update ci-slack-bot.py [#52374](https://github.com/ClickHouse/ClickHouse/pull/52374) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Disable analyzer setting in backward_compatibility integration tests. [#52375](https://github.com/ClickHouse/ClickHouse/pull/52375) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||||
|
* New metric - Filesystem cache size limit [#52378](https://github.com/ClickHouse/ClickHouse/pull/52378) ([Krzysztof Góralski](https://github.com/kgoralski)).
|
||||||
|
* Fix `test_replicated_merge_tree_encrypted_disk ` [#52379](https://github.com/ClickHouse/ClickHouse/pull/52379) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
|
||||||
|
* Fix `02122_parallel_formatting_XML ` [#52380](https://github.com/ClickHouse/ClickHouse/pull/52380) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
|
||||||
|
* Follow up to [#49698](https://github.com/ClickHouse/ClickHouse/issues/49698) [#52381](https://github.com/ClickHouse/ClickHouse/pull/52381) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Less replication errors [#52382](https://github.com/ClickHouse/ClickHouse/pull/52382) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Rename TaskStatsInfoGetter into NetlinkMetricsProvider [#52392](https://github.com/ClickHouse/ClickHouse/pull/52392) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix `test_keeper_force_recovery` [#52408](https://github.com/ClickHouse/ClickHouse/pull/52408) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Fix flaky gtest_lru_file_cache.cpp [#52418](https://github.com/ClickHouse/ClickHouse/pull/52418) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||||
|
* Fix: remove redundant distinct with views [#52438](https://github.com/ClickHouse/ClickHouse/pull/52438) ([Igor Nikonov](https://github.com/devcrafter)).
|
||||||
|
* Add 02815_range_dict_no_direct_join to analyzer_tech_debt.txt [#52464](https://github.com/ClickHouse/ClickHouse/pull/52464) ([vdimir](https://github.com/vdimir)).
|
||||||
|
* do not throw exception in OptimizedRegularExpressionImpl::analyze [#52467](https://github.com/ClickHouse/ClickHouse/pull/52467) ([Han Fei](https://github.com/hanfei1991)).
|
||||||
|
* Remove skip_startup_tables from IDatabase::loadStoredObjects() [#52491](https://github.com/ClickHouse/ClickHouse/pull/52491) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix test_insert_same_partition_and_merge by increasing wait time [#52497](https://github.com/ClickHouse/ClickHouse/pull/52497) ([SmitaRKulkarni](https://github.com/SmitaRKulkarni)).
|
||||||
|
* Try to fix asan wanring in HashJoin [#52499](https://github.com/ClickHouse/ClickHouse/pull/52499) ([Igor Nikonov](https://github.com/devcrafter)).
|
||||||
|
* Replace with three way comparison [#52509](https://github.com/ClickHouse/ClickHouse/pull/52509) ([flynn](https://github.com/ucasfl)).
|
||||||
|
* Fix flakiness of test_version_update_after_mutation by enabling force_remove_data_recursively_on_drop [#52514](https://github.com/ClickHouse/ClickHouse/pull/52514) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix `test_throttling` [#52515](https://github.com/ClickHouse/ClickHouse/pull/52515) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Improve logging macros [#52519](https://github.com/ClickHouse/ClickHouse/pull/52519) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Fix `toDecimalString` function [#52520](https://github.com/ClickHouse/ClickHouse/pull/52520) ([Andrey Zvonov](https://github.com/zvonand)).
|
||||||
|
* Remove unused code [#52527](https://github.com/ClickHouse/ClickHouse/pull/52527) ([Raúl Marín](https://github.com/Algunenano)).
|
||||||
|
* Cancel execution in PipelineExecutor in case of exception in graph->updateNode [#52533](https://github.com/ClickHouse/ClickHouse/pull/52533) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||||
|
* Make 01951_distributed_push_down_limit analyzer agnostic [#52534](https://github.com/ClickHouse/ClickHouse/pull/52534) ([Igor Nikonov](https://github.com/devcrafter)).
|
||||||
|
* Fix disallow_concurrency test for backup and restore [#52536](https://github.com/ClickHouse/ClickHouse/pull/52536) ([SmitaRKulkarni](https://github.com/SmitaRKulkarni)).
|
||||||
|
* Update 02136_scalar_subquery_metrics.sql [#52537](https://github.com/ClickHouse/ClickHouse/pull/52537) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* tests: fix 01035_avg_weighted_long flakiness [#52556](https://github.com/ClickHouse/ClickHouse/pull/52556) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* tests: increase throttling for 01923_network_receive_time_metric_insert [#52557](https://github.com/ClickHouse/ClickHouse/pull/52557) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* tests: fix 00719_parallel_ddl_table flakiness in debug builds [#52558](https://github.com/ClickHouse/ClickHouse/pull/52558) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* tests: fix 01821_join_table_race_long flakiness [#52559](https://github.com/ClickHouse/ClickHouse/pull/52559) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
|
* Fix flaky `00995_exception_while_insert` [#52568](https://github.com/ClickHouse/ClickHouse/pull/52568) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* MaterializedMySQL: Fix typos in tests [#52575](https://github.com/ClickHouse/ClickHouse/pull/52575) ([Val Doroshchuk](https://github.com/valbok)).
|
||||||
|
* Fix `02497_trace_events_stress_long` again [#52587](https://github.com/ClickHouse/ClickHouse/pull/52587) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Revert "Remove `mmap/mremap/munmap` from Allocator.h" [#52589](https://github.com/ClickHouse/ClickHouse/pull/52589) ([Nikita Taranov](https://github.com/nickitat)).
|
||||||
|
* Remove peak memory usage from the final message in the client [#52598](https://github.com/ClickHouse/ClickHouse/pull/52598) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
|
||||||
|
* GinIndexStore: fix a bug when files are finalizated after first write, [#52602](https://github.com/ClickHouse/ClickHouse/pull/52602) ([Sema Checherinda](https://github.com/CheSema)).
|
||||||
|
* Fix deadlocks in StorageTableFunctionProxy [#52626](https://github.com/ClickHouse/ClickHouse/pull/52626) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Fix build with clang-15 [#52627](https://github.com/ClickHouse/ClickHouse/pull/52627) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Fix style [#52647](https://github.com/ClickHouse/ClickHouse/pull/52647) ([Antonio Andelic](https://github.com/antonio2368)).
|
||||||
|
* Fix logging level of a noisy message [#52648](https://github.com/ClickHouse/ClickHouse/pull/52648) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
* Revert "Added field `refcount` to `system.remote_data_paths` table" [#52657](https://github.com/ClickHouse/ClickHouse/pull/52657) ([Alexander Tokmakov](https://github.com/tavplubix)).
|
||||||
|
|
@ -7,12 +7,8 @@ description: How to build Clickhouse and run benchmark with DEFLATE_QPL Codec
|
|||||||
|
|
||||||
# Build Clickhouse with DEFLATE_QPL
|
# Build Clickhouse with DEFLATE_QPL
|
||||||
|
|
||||||
- Make sure your target machine meet the QPL required [prerequisites](https://intel.github.io/qpl/documentation/get_started_docs/installation.html#prerequisites)
|
- Make sure your host machine meet the QPL required [prerequisites](https://intel.github.io/qpl/documentation/get_started_docs/installation.html#prerequisites)
|
||||||
- Pass the following flag to CMake when building ClickHouse:
|
- deflate_qpl is enabled by default during cmake build. In case you accidentally change it, please double-check build flag: ENABLE_QPL=1
|
||||||
|
|
||||||
``` bash
|
|
||||||
cmake -DENABLE_QPL=1 ..
|
|
||||||
```
|
|
||||||
|
|
||||||
- For generic requirements, please refer to Clickhouse generic [build instructions](/docs/en/development/build.md)
|
- For generic requirements, please refer to Clickhouse generic [build instructions](/docs/en/development/build.md)
|
||||||
|
|
||||||
|
@ -57,7 +57,8 @@ Notice that the S3 endpoint in the `ENGINE` configuration uses the parameter tok
|
|||||||
|
|
||||||
:::note
|
:::note
|
||||||
As shown in the example, querying from S3 tables that are partitioned is
|
As shown in the example, querying from S3 tables that are partitioned is
|
||||||
not directly supported at this time, but can be accomplished by querying the bucket contents with a wildcard.
|
not directly supported at this time, but can be accomplished by querying the individual partitions
|
||||||
|
using the S3 table function.
|
||||||
|
|
||||||
The primary use-case for writing
|
The primary use-case for writing
|
||||||
partitioned data in S3 is to enable transferring that data into another
|
partitioned data in S3 is to enable transferring that data into another
|
||||||
@ -127,23 +128,7 @@ FROM s3('http://minio:10000/clickhouse//test_45.csv', 'minioadmin', 'minioadminp
|
|||||||
└────┴────┴────┘
|
└────┴────┴────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Select from all partitions
|
#### Limitation
|
||||||
|
|
||||||
```sql
|
|
||||||
SELECT *
|
|
||||||
FROM s3('http://minio:10000/clickhouse//**', 'minioadmin', 'minioadminpassword', 'CSV')
|
|
||||||
```
|
|
||||||
```response
|
|
||||||
┌─c1─┬─c2─┬─c3─┐
|
|
||||||
│ 3 │ 2 │ 1 │
|
|
||||||
└────┴────┴────┘
|
|
||||||
┌─c1─┬─c2─┬─c3─┐
|
|
||||||
│ 1 │ 2 │ 3 │
|
|
||||||
└────┴────┴────┘
|
|
||||||
┌─c1─┬─c2─┬─c3─┐
|
|
||||||
│ 78 │ 43 │ 45 │
|
|
||||||
└────┴────┴────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
You may naturally try to `Select * from p`, but as noted above, this query will fail; use the preceding query.
|
You may naturally try to `Select * from p`, but as noted above, this query will fail; use the preceding query.
|
||||||
|
|
||||||
|
@ -106,3 +106,4 @@ For partitioning by month, use the `toYYYYMM(date_column)` expression, where `da
|
|||||||
## Storage Settings {#storage-settings}
|
## Storage Settings {#storage-settings}
|
||||||
|
|
||||||
- [engine_url_skip_empty_files](/docs/en/operations/settings/settings.md#engine_url_skip_empty_files) - allows to skip empty files while reading. Disabled by default.
|
- [engine_url_skip_empty_files](/docs/en/operations/settings/settings.md#engine_url_skip_empty_files) - allows to skip empty files while reading. Disabled by default.
|
||||||
|
- [disable_url_encoding](/docs/en/operations/settings/settings.md#disable_url_encoding) -allows to disable decoding/encoding path in uri. Disabled by default.
|
||||||
|
@ -56,7 +56,7 @@ Connection: Close
|
|||||||
Content-Type: text/tab-separated-values; charset=UTF-8
|
Content-Type: text/tab-separated-values; charset=UTF-8
|
||||||
X-ClickHouse-Server-Display-Name: clickhouse.ru-central1.internal
|
X-ClickHouse-Server-Display-Name: clickhouse.ru-central1.internal
|
||||||
X-ClickHouse-Query-Id: 5abe861c-239c-467f-b955-8a201abb8b7f
|
X-ClickHouse-Query-Id: 5abe861c-239c-467f-b955-8a201abb8b7f
|
||||||
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
|
|
||||||
1
|
1
|
||||||
```
|
```
|
||||||
@ -286,9 +286,9 @@ Similarly, you can use ClickHouse sessions in the HTTP protocol. To do this, you
|
|||||||
You can receive information about the progress of a query in `X-ClickHouse-Progress` response headers. To do this, enable [send_progress_in_http_headers](../operations/settings/settings.md#settings-send_progress_in_http_headers). Example of the header sequence:
|
You can receive information about the progress of a query in `X-ClickHouse-Progress` response headers. To do this, enable [send_progress_in_http_headers](../operations/settings/settings.md#settings-send_progress_in_http_headers). Example of the header sequence:
|
||||||
|
|
||||||
``` text
|
``` text
|
||||||
X-ClickHouse-Progress: {"read_rows":"2752512","read_bytes":"240570816","total_rows_to_read":"8880128"}
|
X-ClickHouse-Progress: {"read_rows":"2752512","read_bytes":"240570816","total_rows_to_read":"8880128","peak_memory_usage":"4371480"}
|
||||||
X-ClickHouse-Progress: {"read_rows":"5439488","read_bytes":"482285394","total_rows_to_read":"8880128"}
|
X-ClickHouse-Progress: {"read_rows":"5439488","read_bytes":"482285394","total_rows_to_read":"8880128","peak_memory_usage":"13621616"}
|
||||||
X-ClickHouse-Progress: {"read_rows":"8783786","read_bytes":"819092887","total_rows_to_read":"8880128"}
|
X-ClickHouse-Progress: {"read_rows":"8783786","read_bytes":"819092887","total_rows_to_read":"8880128","peak_memory_usage":"23155600"}
|
||||||
```
|
```
|
||||||
|
|
||||||
Possible header fields:
|
Possible header fields:
|
||||||
@ -416,7 +416,7 @@ $ curl -v 'http://localhost:8123/predefined_query'
|
|||||||
< X-ClickHouse-Format: Template
|
< X-ClickHouse-Format: Template
|
||||||
< X-ClickHouse-Timezone: Asia/Shanghai
|
< X-ClickHouse-Timezone: Asia/Shanghai
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
# HELP "Query" "Number of executing queries"
|
# HELP "Query" "Number of executing queries"
|
||||||
# TYPE "Query" counter
|
# TYPE "Query" counter
|
||||||
@ -581,7 +581,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/hi'
|
|||||||
< Content-Type: text/html; charset=UTF-8
|
< Content-Type: text/html; charset=UTF-8
|
||||||
< Transfer-Encoding: chunked
|
< Transfer-Encoding: chunked
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
* Connection #0 to host localhost left intact
|
* Connection #0 to host localhost left intact
|
||||||
Say Hi!%
|
Say Hi!%
|
||||||
@ -621,7 +621,7 @@ $ curl -v -H 'XXX:xxx' 'http://localhost:8123/get_config_static_handler'
|
|||||||
< Content-Type: text/plain; charset=UTF-8
|
< Content-Type: text/plain; charset=UTF-8
|
||||||
< Transfer-Encoding: chunked
|
< Transfer-Encoding: chunked
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
* Connection #0 to host localhost left intact
|
* Connection #0 to host localhost left intact
|
||||||
<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>%
|
<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>%
|
||||||
@ -673,7 +673,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_absolute_path_static_handler'
|
|||||||
< Content-Type: text/html; charset=UTF-8
|
< Content-Type: text/html; charset=UTF-8
|
||||||
< Transfer-Encoding: chunked
|
< Transfer-Encoding: chunked
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
<html><body>Absolute Path File</body></html>
|
<html><body>Absolute Path File</body></html>
|
||||||
* Connection #0 to host localhost left intact
|
* Connection #0 to host localhost left intact
|
||||||
@ -692,7 +692,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_relative_path_static_handler'
|
|||||||
< Content-Type: text/html; charset=UTF-8
|
< Content-Type: text/html; charset=UTF-8
|
||||||
< Transfer-Encoding: chunked
|
< Transfer-Encoding: chunked
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
<html><body>Relative Path File</body></html>
|
<html><body>Relative Path File</body></html>
|
||||||
* Connection #0 to host localhost left intact
|
* Connection #0 to host localhost left intact
|
||||||
|
@ -65,6 +65,40 @@ XML substitution example:
|
|||||||
|
|
||||||
Substitutions can also be performed from ZooKeeper. To do this, specify the attribute `from_zk = "/path/to/node"`. The element value is replaced with the contents of the node at `/path/to/node` in ZooKeeper. You can also put an entire XML subtree on the ZooKeeper node and it will be fully inserted into the source element.
|
Substitutions can also be performed from ZooKeeper. To do this, specify the attribute `from_zk = "/path/to/node"`. The element value is replaced with the contents of the node at `/path/to/node` in ZooKeeper. You can also put an entire XML subtree on the ZooKeeper node and it will be fully inserted into the source element.
|
||||||
|
|
||||||
|
## Encrypting Configuration {#encryption}
|
||||||
|
|
||||||
|
You can use symmetric encryption to encrypt a configuration element, for example, a password field. To do so, first configure the [encryption codec](../sql-reference/statements/create/table.md#encryption-codecs), then add attribute `encryption_codec` with the name of the encryption codec as value to the element to encrypt.
|
||||||
|
|
||||||
|
Unlike attributes `from_zk`, `from_env` and `incl` (or element `include`), no substitution, i.e. decryption of the encrypted value, is performed in the preprocessed file. Decryption happens only at runtime in the server process.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<clickhouse>
|
||||||
|
<encryption_codecs>
|
||||||
|
<aes_128_gcm_siv>
|
||||||
|
<key_hex>00112233445566778899aabbccddeeff</key_hex>
|
||||||
|
</aes_128_gcm_siv>
|
||||||
|
</encryption_codecs>
|
||||||
|
<interserver_http_credentials>
|
||||||
|
<user>admin</user>
|
||||||
|
<password encryption_codec="AES_128_GCM_SIV">961F000000040000000000EEDDEF4F453CFE6457C4234BD7C09258BD651D85</password>
|
||||||
|
</interserver_http_credentials>
|
||||||
|
</clickhouse>
|
||||||
|
```
|
||||||
|
|
||||||
|
To get the encrypted value `encrypt_decrypt` example application may be used.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
./encrypt_decrypt /etc/clickhouse-server/config.xml -e AES_128_GCM_SIV abcd
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
961F000000040000000000EEDDEF4F453CFE6457C4234BD7C09258BD651D85
|
||||||
|
```
|
||||||
|
|
||||||
## User Settings {#user-settings}
|
## User Settings {#user-settings}
|
||||||
|
|
||||||
The `config.xml` file can specify a separate config with user settings, profiles, and quotas. The relative path to this config is set in the `users_config` element. By default, it is `users.xml`. If `users_config` is omitted, the user settings, profiles, and quotas are specified directly in `config.xml`.
|
The `config.xml` file can specify a separate config with user settings, profiles, and quotas. The relative path to this config is set in the `users_config` element. By default, it is `users.xml`. If `users_config` is omitted, the user settings, profiles, and quotas are specified directly in `config.xml`.
|
||||||
|
@ -62,8 +62,10 @@ may return cached results then.
|
|||||||
|
|
||||||
The query cache can be cleared using statement `SYSTEM DROP QUERY CACHE`. The content of the query cache is displayed in system table
|
The query cache can be cleared using statement `SYSTEM DROP QUERY CACHE`. The content of the query cache is displayed in system table
|
||||||
`system.query_cache`. The number of query cache hits and misses are shown as events "QueryCacheHits" and "QueryCacheMisses" in system table
|
`system.query_cache`. The number of query cache hits and misses are shown as events "QueryCacheHits" and "QueryCacheMisses" in system table
|
||||||
`system.events`. Both counters are only updated for `SELECT` queries which run with setting "use_query_cache = true". Other queries do not
|
[system.events](system-tables/events.md). Both counters are only updated for `SELECT` queries which run with setting "use_query_cache =
|
||||||
affect the cache miss counter.
|
true". Other queries do not affect the cache miss counter. Field `query_log_usage` in system table
|
||||||
|
[system.query_log](system-tables/query_log.md) shows for each ran query whether the query result was written into or read from the query
|
||||||
|
cache.
|
||||||
|
|
||||||
The query cache exists once per ClickHouse server process. However, cache results are by default not shared between users. This can be
|
The query cache exists once per ClickHouse server process. However, cache results are by default not shared between users. This can be
|
||||||
changed (see below) but doing so is not recommended for security reasons.
|
changed (see below) but doing so is not recommended for security reasons.
|
||||||
|
@ -3468,6 +3468,12 @@ Possible values:
|
|||||||
|
|
||||||
Default value: `0`.
|
Default value: `0`.
|
||||||
|
|
||||||
|
## disable_url_encoding {#disable_url_encoding}
|
||||||
|
|
||||||
|
Allows to disable decoding/encoding path in uri in [URL](../../engines/table-engines/special/url.md) engine tables.
|
||||||
|
|
||||||
|
Disabled by default.
|
||||||
|
|
||||||
## database_atomic_wait_for_drop_and_detach_synchronously {#database_atomic_wait_for_drop_and_detach_synchronously}
|
## database_atomic_wait_for_drop_and_detach_synchronously {#database_atomic_wait_for_drop_and_detach_synchronously}
|
||||||
|
|
||||||
Adds a modifier `SYNC` to all `DROP` and `DETACH` queries.
|
Adds a modifier `SYNC` to all `DROP` and `DETACH` queries.
|
||||||
|
@ -111,6 +111,11 @@ Columns:
|
|||||||
- `used_functions` ([Array(String)](../../sql-reference/data-types/array.md)) — Canonical names of `functions`, which were used during query execution.
|
- `used_functions` ([Array(String)](../../sql-reference/data-types/array.md)) — Canonical names of `functions`, which were used during query execution.
|
||||||
- `used_storages` ([Array(String)](../../sql-reference/data-types/array.md)) — Canonical names of `storages`, which were used during query execution.
|
- `used_storages` ([Array(String)](../../sql-reference/data-types/array.md)) — Canonical names of `storages`, which were used during query execution.
|
||||||
- `used_table_functions` ([Array(String)](../../sql-reference/data-types/array.md)) — Canonical names of `table functions`, which were used during query execution.
|
- `used_table_functions` ([Array(String)](../../sql-reference/data-types/array.md)) — Canonical names of `table functions`, which were used during query execution.
|
||||||
|
- `query_cache_usage` ([Enum8](../../sql-reference/data-types/enum.md)) — Usage of the [query cache](../query-cache.md) during query execution. Values:
|
||||||
|
- `'Unknown'` = Status unknown.
|
||||||
|
- `'None'` = The query result was neither written into nor read from the query cache.
|
||||||
|
- `'Write'` = The query result was written into the query cache.
|
||||||
|
- `'Read'` = The query result was read from the query cache.
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
|
|
||||||
@ -186,6 +191,7 @@ used_formats: []
|
|||||||
used_functions: []
|
used_functions: []
|
||||||
used_storages: []
|
used_storages: []
|
||||||
used_table_functions: []
|
used_table_functions: []
|
||||||
|
query_cache_usage: None
|
||||||
```
|
```
|
||||||
|
|
||||||
**See Also**
|
**See Also**
|
||||||
|
@ -12,3 +12,5 @@ To get a determinate result, you can use the ‘min’ or ‘max’ function ins
|
|||||||
In some cases, you can rely on the order of execution. This applies to cases when SELECT comes from a subquery that uses ORDER BY.
|
In some cases, you can rely on the order of execution. This applies to cases when SELECT comes from a subquery that uses ORDER BY.
|
||||||
|
|
||||||
When a `SELECT` query has the `GROUP BY` clause or at least one aggregate function, ClickHouse (in contrast to MySQL) requires that all expressions in the `SELECT`, `HAVING`, and `ORDER BY` clauses be calculated from keys or from aggregate functions. In other words, each column selected from the table must be used either in keys or inside aggregate functions. To get behavior like in MySQL, you can put the other columns in the `any` aggregate function.
|
When a `SELECT` query has the `GROUP BY` clause or at least one aggregate function, ClickHouse (in contrast to MySQL) requires that all expressions in the `SELECT`, `HAVING`, and `ORDER BY` clauses be calculated from keys or from aggregate functions. In other words, each column selected from the table must be used either in keys or inside aggregate functions. To get behavior like in MySQL, you can put the other columns in the `any` aggregate function.
|
||||||
|
|
||||||
|
- Alias: `any_value`
|
||||||
|
@ -575,6 +575,42 @@ Alias:
|
|||||||
|
|
||||||
Like `substring` but for Unicode code points. Assumes that the string contains valid UTF-8 encoded text. If this assumption is violated, no exception is thrown and the result is undefined.
|
Like `substring` but for Unicode code points. Assumes that the string contains valid UTF-8 encoded text. If this assumption is violated, no exception is thrown and the result is undefined.
|
||||||
|
|
||||||
|
|
||||||
|
## substringIndex(s, delim, count)
|
||||||
|
|
||||||
|
Returns the substring of `s` before `count` occurrences of the delimiter `delim`, as in Spark or MySQL.
|
||||||
|
|
||||||
|
**Syntax**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
substringIndex(s, delim, count)
|
||||||
|
```
|
||||||
|
Alias: `SUBSTRING_INDEX`
|
||||||
|
|
||||||
|
|
||||||
|
**Arguments**
|
||||||
|
|
||||||
|
- s: The string to extract substring from. [String](../../sql-reference/data-types/string.md).
|
||||||
|
- delim: The character to split. [String](../../sql-reference/data-types/string.md).
|
||||||
|
- count: The number of occurrences of the delimiter to count before extracting the substring. If count is positive, everything to the left of the final delimiter (counting from the left) is returned. If count is negative, everything to the right of the final delimiter (counting from the right) is returned. [UInt or Int](../data-types/int-uint.md)
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT substringIndex('www.clickhouse.com', '.', 2)
|
||||||
|
```
|
||||||
|
|
||||||
|
Result:
|
||||||
|
```
|
||||||
|
┌─substringIndex('www.clickhouse.com', '.', 2)─┐
|
||||||
|
│ www.clickhouse │
|
||||||
|
└──────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## substringIndexUTF8(s, delim, count)
|
||||||
|
|
||||||
|
Like `substringIndex` but for Unicode code points. Assumes that the string contains valid UTF-8 encoded text. If this assumption is violated, no exception is thrown and the result is undefined.
|
||||||
|
|
||||||
## appendTrailingCharIfAbsent
|
## appendTrailingCharIfAbsent
|
||||||
|
|
||||||
Appends character `c` to string `s` if `s` is non-empty and does not end with character `c`.
|
Appends character `c` to string `s` if `s` is non-empty and does not end with character `c`.
|
||||||
|
@ -945,6 +945,44 @@ Result:
|
|||||||
└────────────┴───────┘
|
└────────────┴───────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## toDecimalString
|
||||||
|
|
||||||
|
Converts a numeric value to String with the number of fractional digits in the output specified by the user.
|
||||||
|
|
||||||
|
**Syntax**
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
toDecimalString(number, scale)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `number` — Value to be represented as String, [Int, UInt](/docs/en/sql-reference/data-types/int-uint.md), [Float](/docs/en/sql-reference/data-types/float.md), [Decimal](/docs/en/sql-reference/data-types/decimal.md),
|
||||||
|
- `scale` — Number of fractional digits, [UInt8](/docs/en/sql-reference/data-types/int-uint.md).
|
||||||
|
* Maximum scale for [Decimal](/docs/en/sql-reference/data-types/decimal.md) and [Int, UInt](/docs/en/sql-reference/data-types/int-uint.md) types is 77 (it is the maximum possible number of significant digits for Decimal),
|
||||||
|
* Maximum scale for [Float](/docs/en/sql-reference/data-types/float.md) is 60.
|
||||||
|
|
||||||
|
**Returned value**
|
||||||
|
|
||||||
|
- Input value represented as [String](/docs/en/sql-reference/data-types/string.md) with given number of fractional digits (scale).
|
||||||
|
The number is rounded up or down according to common arithmetic in case requested scale is smaller than original number's scale.
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
Query:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT toDecimalString(CAST('64.32', 'Float64'), 5);
|
||||||
|
```
|
||||||
|
|
||||||
|
Result:
|
||||||
|
|
||||||
|
```response
|
||||||
|
┌toDecimalString(CAST('64.32', 'Float64'), 5)─┐
|
||||||
|
│ 64.32000 │
|
||||||
|
└─────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
## reinterpretAsUInt(8\|16\|32\|64)
|
## reinterpretAsUInt(8\|16\|32\|64)
|
||||||
|
|
||||||
## reinterpretAsInt(8\|16\|32\|64)
|
## reinterpretAsInt(8\|16\|32\|64)
|
||||||
|
@ -213,7 +213,7 @@ Removes one of the column properties: `DEFAULT`, `ALIAS`, `MATERIALIZED`, `CODEC
|
|||||||
Syntax:
|
Syntax:
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
ALTER TABLE table_name MODIFY column_name REMOVE property;
|
ALTER TABLE table_name MODIFY COLUMN column_name REMOVE property;
|
||||||
```
|
```
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
|
@ -414,3 +414,29 @@ Will do sync syscall.
|
|||||||
```sql
|
```sql
|
||||||
SYSTEM SYNC FILE CACHE [ON CLUSTER cluster_name]
|
SYSTEM SYNC FILE CACHE [ON CLUSTER cluster_name]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### SYSTEM STOP LISTEN
|
||||||
|
|
||||||
|
Closes the socket and gracefully terminates the existing connections to the server on the specified port with the specified protocol.
|
||||||
|
|
||||||
|
However, if the corresponding protocol settings were not specified in the clickhouse-server configuration, this command will have no effect.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SYSTEM STOP LISTEN [ON CLUSTER cluster_name] [QUERIES ALL | QUERIES DEFAULT | QUERIES CUSTOM | TCP | TCP_WITH_PROXY | TCP_SECURE | HTTP | HTTPS | MYSQL | GRPC | POSTGRESQL | PROMETHEUS | CUSTOM 'protocol']
|
||||||
|
```
|
||||||
|
|
||||||
|
- If `CUSTOM 'protocol'` modifier is specified, the custom protocol with the specified name defined in the protocols section of the server configuration will be stopped.
|
||||||
|
- If `QUERIES ALL` modifier is specified, all protocols are stopped.
|
||||||
|
- If `QUERIES DEFAULT` modifier is specified, all default protocols are stopped.
|
||||||
|
- If `QUERIES CUSTOM` modifier is specified, all custom protocols are stopped.
|
||||||
|
|
||||||
|
### SYSTEM START LISTEN
|
||||||
|
|
||||||
|
Allows new connections to be established on the specified protocols.
|
||||||
|
|
||||||
|
However, if the server on the specified port and protocol was not stopped using the SYSTEM STOP LISTEN command, this command will have no effect.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SYSTEM START LISTEN [ON CLUSTER cluster_name] [QUERIES ALL | QUERIES DEFAULT | QUERIES CUSTOM | TCP | TCP_WITH_PROXY | TCP_SECURE | HTTP | HTTPS | MYSQL | GRPC | POSTGRESQL | PROMETHEUS | CUSTOM 'protocol']
|
||||||
|
```
|
||||||
|
@ -56,6 +56,7 @@ Character `|` inside patterns is used to specify failover addresses. They are it
|
|||||||
## Storage Settings {#storage-settings}
|
## Storage Settings {#storage-settings}
|
||||||
|
|
||||||
- [engine_url_skip_empty_files](/docs/en/operations/settings/settings.md#engine_url_skip_empty_files) - allows to skip empty files while reading. Disabled by default.
|
- [engine_url_skip_empty_files](/docs/en/operations/settings/settings.md#engine_url_skip_empty_files) - allows to skip empty files while reading. Disabled by default.
|
||||||
|
- [disable_url_encoding](/docs/en/operations/settings/settings.md#disable_url_encoding) - allows to disable decoding/encoding path in uri. Disabled by default.
|
||||||
|
|
||||||
**See Also**
|
**See Also**
|
||||||
|
|
||||||
|
@ -3,23 +3,46 @@ slug: /en/guides/developer/transactional
|
|||||||
---
|
---
|
||||||
# Transactional (ACID) support
|
# Transactional (ACID) support
|
||||||
|
|
||||||
INSERT into one partition* in one table* of MergeTree* family up to max_insert_block_size rows* is transactional (ACID):
|
## Case 1: INSERT into one partition, of one table, of the MergeTree* family
|
||||||
- Atomic: INSERT is succeeded or rejected as a whole: if confirmation is sent to the client, all rows INSERTed; if error is sent to the client, no rows INSERTed.
|
|
||||||
|
This is transactional (ACID) if the inserted rows are packed and inserted as a single block (see Notes):
|
||||||
|
- Atomic: an INSERT succeeds or is rejected as a whole: if a confirmation is sent to the client, then all rows were inserted; if an error is sent to the client, then no rows were inserted.
|
||||||
- Consistent: if there are no table constraints violated, then all rows in an INSERT are inserted and the INSERT succeeds; if constraints are violated, then no rows are inserted.
|
- Consistent: if there are no table constraints violated, then all rows in an INSERT are inserted and the INSERT succeeds; if constraints are violated, then no rows are inserted.
|
||||||
- Isolated: concurrent clients observe a consistent snapshot of the table–the state of the table either as if before INSERT or after successful INSERT; no partial state is seen;
|
- Isolated: concurrent clients observe a consistent snapshot of the table–the state of the table either as it was before the INSERT attempt, or after the successful INSERT; no partial state is seen
|
||||||
- Durable: successful INSERT is written to the filesystem before answering to the client, on single replica or multiple replicas (controlled by the `insert_quorum` setting), and ClickHouse can ask the OS to sync the filesystem data on the storage media (controlled by the `fsync_after_insert` setting).
|
- Durable: a successful INSERT is written to the filesystem before answering to the client, on a single replica or multiple replicas (controlled by the `insert_quorum` setting), and ClickHouse can ask the OS to sync the filesystem data on the storage media (controlled by the `fsync_after_insert` setting).
|
||||||
* If table has many partitions and INSERT covers many partitions–then insertion into every partition is transactional on its own;
|
- INSERT into multiple tables with one statement is possible if materialized views are involved (the INSERT from the client is to a table which has associate materialized views).
|
||||||
* INSERT into multiple tables with one statement is possible if materialized views are involved;
|
|
||||||
* INSERT into Distributed table is not transactional as a whole, while insertion into every shard is transactional;
|
## Case 2: INSERT into multiple partitions, of one table, of the MergeTree* family
|
||||||
* another example: insert into Buffer tables is neither atomic nor isolated or consistent or durable;
|
|
||||||
* atomicity is ensured even if `async_insert` is enabled, but it can be turned off by the wait_for_async_insert setting;
|
Same as Case 1 above, with this detail:
|
||||||
* max_insert_block_size is 1 000 000 by default and can be adjusted as needed;
|
- If table has many partitions and INSERT covers many partitions–then insertion into every partition is transactional on its own
|
||||||
* if client did not receive the answer from the server, the client does not know if transaction succeeded, and it can repeat the transaction, using exactly-once insertion properties;
|
|
||||||
* ClickHouse is using MVCC with snapshot isolation internally;
|
|
||||||
* all ACID properties are valid even in case of server kill / crash;
|
## Case 3: INSERT into one distributed table of the MergeTree* family
|
||||||
* either insert_quorum into different AZ or fsync should be enabled to ensure durable inserts in typical setup;
|
|
||||||
* "consistency" in ACID terms does not cover the semantics of distributed systems, see https://jepsen.io/consistency which is controlled by different settings (select_sequential_consistency)
|
Same as Case 1 above, with this detail:
|
||||||
* this explanation does not cover a new transactions feature that allow to have full-featured transactions over multiple tables, materialized views, for multiple SELECTs, etc.
|
- INSERT into Distributed table is not transactional as a whole, while insertion into every shard is transactional
|
||||||
|
|
||||||
|
## Case 4: Using a Buffer table
|
||||||
|
|
||||||
|
- insert into Buffer tables is neither atomic nor isolated nor consistent nor durable
|
||||||
|
|
||||||
|
## Case 5: Using async_insert
|
||||||
|
|
||||||
|
Same as Case 1 above, with this detail:
|
||||||
|
- atomicity is ensured even if `async_insert` is enabled and `wait_for_async_insert` is set to 1 (the default), but if `wait_for_async_insert` is set to 0, then atomicity is not ensured.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- rows inserted from the client in some data format are packed into a single block when:
|
||||||
|
- the insert format is row-based (like CSV, TSV, Values, JSONEachRow, etc) and the data contains less then `max_insert_block_size` rows (~1 000 000 by default) or less then `min_chunk_bytes_for_parallel_parsing` bytes (10 MB by default) in case of parallel parsing is used (enabled by default)
|
||||||
|
- the insert format is column-based (like Native, Parquet, ORC, etc) and the data contains only one block of data
|
||||||
|
- the size of the inserted block in general may depend on many settings (for example: `max_block_size`, `max_insert_block_size`, `min_insert_block_size_rows`, `min_insert_block_size_bytes`, `preferred_block_size_bytes`, etc)
|
||||||
|
- if the client did not receive an answer from the server, the client does not know if the transaction succeeded, and it can repeat the transaction, using exactly-once insertion properties
|
||||||
|
- ClickHouse is using MVCC with snapshot isolation internally
|
||||||
|
- all ACID properties are valid even in the case of server kill/crash
|
||||||
|
- either insert_quorum into different AZ or fsync should be enabled to ensure durable inserts in the typical setup
|
||||||
|
- "consistency" in ACID terms does not cover the semantics of distributed systems, see https://jepsen.io/consistency which is controlled by different settings (select_sequential_consistency)
|
||||||
|
- this explanation does not cover a new transactions feature that allow to have full-featured transactions over multiple tables, materialized views, for multiple SELECTs, etc. (see the next section on Transactions, Commit, and Rollback)
|
||||||
|
|
||||||
## Transactions, Commit, and Rollback
|
## Transactions, Commit, and Rollback
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ Connection: Close
|
|||||||
Content-Type: text/tab-separated-values; charset=UTF-8
|
Content-Type: text/tab-separated-values; charset=UTF-8
|
||||||
X-ClickHouse-Server-Display-Name: clickhouse.ru-central1.internal
|
X-ClickHouse-Server-Display-Name: clickhouse.ru-central1.internal
|
||||||
X-ClickHouse-Query-Id: 5abe861c-239c-467f-b955-8a201abb8b7f
|
X-ClickHouse-Query-Id: 5abe861c-239c-467f-b955-8a201abb8b7f
|
||||||
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
|
|
||||||
1
|
1
|
||||||
```
|
```
|
||||||
@ -266,9 +266,9 @@ $ echo 'SELECT number FROM system.numbers LIMIT 10' | curl 'http://localhost:812
|
|||||||
Прогресс выполнения запроса можно отслеживать с помощью заголовков ответа `X-ClickHouse-Progress`. Для этого включите [send_progress_in_http_headers](../operations/settings/settings.md#settings-send_progress_in_http_headers). Пример последовательности заголовков:
|
Прогресс выполнения запроса можно отслеживать с помощью заголовков ответа `X-ClickHouse-Progress`. Для этого включите [send_progress_in_http_headers](../operations/settings/settings.md#settings-send_progress_in_http_headers). Пример последовательности заголовков:
|
||||||
|
|
||||||
``` text
|
``` text
|
||||||
X-ClickHouse-Progress: {"read_rows":"2752512","read_bytes":"240570816","total_rows_to_read":"8880128"}
|
X-ClickHouse-Progress: {"read_rows":"2752512","read_bytes":"240570816","total_rows_to_read":"8880128","peak_memory_usage":"4371480"}
|
||||||
X-ClickHouse-Progress: {"read_rows":"5439488","read_bytes":"482285394","total_rows_to_read":"8880128"}
|
X-ClickHouse-Progress: {"read_rows":"5439488","read_bytes":"482285394","total_rows_to_read":"8880128","peak_memory_usage":"13621616"}
|
||||||
X-ClickHouse-Progress: {"read_rows":"8783786","read_bytes":"819092887","total_rows_to_read":"8880128"}
|
X-ClickHouse-Progress: {"read_rows":"8783786","read_bytes":"819092887","total_rows_to_read":"8880128","peak_memory_usage":"23155600"}
|
||||||
```
|
```
|
||||||
|
|
||||||
Возможные поля заголовка:
|
Возможные поля заголовка:
|
||||||
@ -529,7 +529,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/hi'
|
|||||||
< Content-Type: text/html; charset=UTF-8
|
< Content-Type: text/html; charset=UTF-8
|
||||||
< Transfer-Encoding: chunked
|
< Transfer-Encoding: chunked
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
* Connection #0 to host localhost left intact
|
* Connection #0 to host localhost left intact
|
||||||
Say Hi!%
|
Say Hi!%
|
||||||
@ -569,7 +569,7 @@ $ curl -v -H 'XXX:xxx' 'http://localhost:8123/get_config_static_handler'
|
|||||||
< Content-Type: text/plain; charset=UTF-8
|
< Content-Type: text/plain; charset=UTF-8
|
||||||
< Transfer-Encoding: chunked
|
< Transfer-Encoding: chunked
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
* Connection #0 to host localhost left intact
|
* Connection #0 to host localhost left intact
|
||||||
<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>%
|
<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>%
|
||||||
@ -621,7 +621,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_absolute_path_static_handler'
|
|||||||
< Content-Type: text/html; charset=UTF-8
|
< Content-Type: text/html; charset=UTF-8
|
||||||
< Transfer-Encoding: chunked
|
< Transfer-Encoding: chunked
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
<html><body>Absolute Path File</body></html>
|
<html><body>Absolute Path File</body></html>
|
||||||
* Connection #0 to host localhost left intact
|
* Connection #0 to host localhost left intact
|
||||||
@ -640,7 +640,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_relative_path_static_handler'
|
|||||||
< Content-Type: text/html; charset=UTF-8
|
< Content-Type: text/html; charset=UTF-8
|
||||||
< Transfer-Encoding: chunked
|
< Transfer-Encoding: chunked
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
<html><body>Relative Path File</body></html>
|
<html><body>Relative Path File</body></html>
|
||||||
* Connection #0 to host localhost left intact
|
* Connection #0 to host localhost left intact
|
||||||
|
@ -85,6 +85,40 @@ $ cat /etc/clickhouse-server/users.d/alice.xml
|
|||||||
|
|
||||||
Сервер следит за изменениями конфигурационных файлов, а также файлов и ZooKeeper-узлов, которые были использованы при выполнении подстановок и переопределений, и перезагружает настройки пользователей и кластеров на лету. То есть, можно изменять кластера, пользователей и их настройки без перезапуска сервера.
|
Сервер следит за изменениями конфигурационных файлов, а также файлов и ZooKeeper-узлов, которые были использованы при выполнении подстановок и переопределений, и перезагружает настройки пользователей и кластеров на лету. То есть, можно изменять кластера, пользователей и их настройки без перезапуска сервера.
|
||||||
|
|
||||||
|
## Шифрование {#encryption}
|
||||||
|
|
||||||
|
Вы можете использовать симметричное шифрование для зашифровки элемента конфигурации, например, поля password. Чтобы это сделать, сначала настройте [кодек шифрования](../sql-reference/statements/create/table.md#encryption-codecs), затем добавьте аттибут`encryption_codec` с именем кодека шифрования как значение к элементу, который надо зашифровать.
|
||||||
|
|
||||||
|
В отличии от аттрибутов `from_zk`, `from_env` и `incl` (или элемента `include`), подстановка, т.е. расшифровка зашифрованного значения, не выподняется в файле предобработки. Расшифровка происходит только во время исполнения в серверном процессе.
|
||||||
|
|
||||||
|
Пример:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<clickhouse>
|
||||||
|
<encryption_codecs>
|
||||||
|
<aes_128_gcm_siv>
|
||||||
|
<key_hex>00112233445566778899aabbccddeeff</key_hex>
|
||||||
|
</aes_128_gcm_siv>
|
||||||
|
</encryption_codecs>
|
||||||
|
<interserver_http_credentials>
|
||||||
|
<user>admin</user>
|
||||||
|
<password encryption_codec="AES_128_GCM_SIV">961F000000040000000000EEDDEF4F453CFE6457C4234BD7C09258BD651D85</password>
|
||||||
|
</interserver_http_credentials>
|
||||||
|
</clickhouse>
|
||||||
|
```
|
||||||
|
|
||||||
|
Чтобы получить зашифрованное значение может быть использовано приложение-пример `encrypt_decrypt` .
|
||||||
|
|
||||||
|
Пример:
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
./encrypt_decrypt /etc/clickhouse-server/config.xml -e AES_128_GCM_SIV abcd
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
961F000000040000000000EEDDEF4F453CFE6457C4234BD7C09258BD651D85
|
||||||
|
```
|
||||||
|
|
||||||
## Примеры записи конфигурации на YAML {#example}
|
## Примеры записи конфигурации на YAML {#example}
|
||||||
|
|
||||||
Здесь можно рассмотреть пример реальной конфигурации записанной на YAML: [config.yaml.example](https://github.com/ClickHouse/ClickHouse/blob/master/programs/server/config.yaml.example).
|
Здесь можно рассмотреть пример реальной конфигурации записанной на YAML: [config.yaml.example](https://github.com/ClickHouse/ClickHouse/blob/master/programs/server/config.yaml.example).
|
||||||
|
@ -762,6 +762,44 @@ SELECT toFixedString('foo\0bar', 8) AS s, toStringCutToZero(s) AS s_cut;
|
|||||||
└────────────┴───────┘
|
└────────────┴───────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## toDecimalString
|
||||||
|
|
||||||
|
Принимает любой численный тип первым аргументом, возвращает строковое десятичное представление числа с точностью, заданной вторым аргументом.
|
||||||
|
|
||||||
|
**Синтаксис**
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
toDecimalString(number, scale)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Параметры**
|
||||||
|
|
||||||
|
- `number` — Значение любого числового типа: [Int, UInt](/docs/ru/sql-reference/data-types/int-uint.md), [Float](/docs/ru/sql-reference/data-types/float.md), [Decimal](/docs/ru/sql-reference/data-types/decimal.md),
|
||||||
|
- `scale` — Требуемое количество десятичных знаков после запятой, [UInt8](/docs/ru/sql-reference/data-types/int-uint.md).
|
||||||
|
* Значение `scale` для типов [Decimal](/docs/ru/sql-reference/data-types/decimal.md) и [Int, UInt](/docs/ru/sql-reference/data-types/int-uint.md) должно не превышать 77 (так как это наибольшее количество значимых символов для этих типов),
|
||||||
|
* Значение `scale` для типа [Float](/docs/ru/sql-reference/data-types/float.md) не должно превышать 60.
|
||||||
|
|
||||||
|
**Возвращаемое значение**
|
||||||
|
|
||||||
|
- Строка ([String](/docs/en/sql-reference/data-types/string.md)), представляющая собой десятичное представление входного числа с заданной длиной дробной части.
|
||||||
|
При необходимости число округляется по стандартным правилам арифметики.
|
||||||
|
|
||||||
|
**Пример использования**
|
||||||
|
|
||||||
|
Запрос:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT toDecimalString(CAST('64.32', 'Float64'), 5);
|
||||||
|
```
|
||||||
|
|
||||||
|
Результат:
|
||||||
|
|
||||||
|
```response
|
||||||
|
┌─toDecimalString(CAST('64.32', 'Float64'), 5)┐
|
||||||
|
│ 64.32000 │
|
||||||
|
└─────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
## reinterpretAsUInt(8\|16\|32\|64) {#reinterpretasuint8163264}
|
## reinterpretAsUInt(8\|16\|32\|64) {#reinterpretasuint8163264}
|
||||||
|
|
||||||
## reinterpretAsInt(8\|16\|32\|64) {#reinterpretasint8163264}
|
## reinterpretAsInt(8\|16\|32\|64) {#reinterpretasint8163264}
|
||||||
|
@ -182,7 +182,7 @@ ALTER TABLE visits MODIFY COLUMN browser Array(String)
|
|||||||
Синтаксис:
|
Синтаксис:
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
ALTER TABLE table_name MODIFY column_name REMOVE property;
|
ALTER TABLE table_name MODIFY COLUMN column_name REMOVE property;
|
||||||
```
|
```
|
||||||
|
|
||||||
**Пример**
|
**Пример**
|
||||||
|
@ -53,7 +53,7 @@ Connection: Close
|
|||||||
Content-Type: text/tab-separated-values; charset=UTF-8
|
Content-Type: text/tab-separated-values; charset=UTF-8
|
||||||
X-ClickHouse-Server-Display-Name: clickhouse.ru-central1.internal
|
X-ClickHouse-Server-Display-Name: clickhouse.ru-central1.internal
|
||||||
X-ClickHouse-Query-Id: 5abe861c-239c-467f-b955-8a201abb8b7f
|
X-ClickHouse-Query-Id: 5abe861c-239c-467f-b955-8a201abb8b7f
|
||||||
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
|
|
||||||
1
|
1
|
||||||
```
|
```
|
||||||
@ -262,9 +262,9 @@ $ echo 'SELECT number FROM system.numbers LIMIT 10' | curl 'http://localhost:812
|
|||||||
您可以在`X-ClickHouse-Progress`响应头中收到查询进度的信息。为此,启用[Http Header携带进度](../operations/settings/settings.md#settings-send_progress_in_http_headers)。示例:
|
您可以在`X-ClickHouse-Progress`响应头中收到查询进度的信息。为此,启用[Http Header携带进度](../operations/settings/settings.md#settings-send_progress_in_http_headers)。示例:
|
||||||
|
|
||||||
``` text
|
``` text
|
||||||
X-ClickHouse-Progress: {"read_rows":"2752512","read_bytes":"240570816","total_rows_to_read":"8880128"}
|
X-ClickHouse-Progress: {"read_rows":"2752512","read_bytes":"240570816","total_rows_to_read":"8880128","peak_memory_usage":"4371480"}
|
||||||
X-ClickHouse-Progress: {"read_rows":"5439488","read_bytes":"482285394","total_rows_to_read":"8880128"}
|
X-ClickHouse-Progress: {"read_rows":"5439488","read_bytes":"482285394","total_rows_to_read":"8880128","peak_memory_usage":"13621616"}
|
||||||
X-ClickHouse-Progress: {"read_rows":"8783786","read_bytes":"819092887","total_rows_to_read":"8880128"}
|
X-ClickHouse-Progress: {"read_rows":"8783786","read_bytes":"819092887","total_rows_to_read":"8880128","peak_memory_usage":"23155600"}
|
||||||
```
|
```
|
||||||
|
|
||||||
显示字段信息:
|
显示字段信息:
|
||||||
@ -363,7 +363,7 @@ $ curl -v 'http://localhost:8123/predefined_query'
|
|||||||
< X-ClickHouse-Format: Template
|
< X-ClickHouse-Format: Template
|
||||||
< X-ClickHouse-Timezone: Asia/Shanghai
|
< X-ClickHouse-Timezone: Asia/Shanghai
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
# HELP "Query" "Number of executing queries"
|
# HELP "Query" "Number of executing queries"
|
||||||
# TYPE "Query" counter
|
# TYPE "Query" counter
|
||||||
@ -521,7 +521,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/hi'
|
|||||||
< Content-Type: text/html; charset=UTF-8
|
< Content-Type: text/html; charset=UTF-8
|
||||||
< Transfer-Encoding: chunked
|
< Transfer-Encoding: chunked
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
* Connection #0 to host localhost left intact
|
* Connection #0 to host localhost left intact
|
||||||
Say Hi!%
|
Say Hi!%
|
||||||
@ -561,7 +561,7 @@ $ curl -v -H 'XXX:xxx' 'http://localhost:8123/get_config_static_handler'
|
|||||||
< Content-Type: text/plain; charset=UTF-8
|
< Content-Type: text/plain; charset=UTF-8
|
||||||
< Transfer-Encoding: chunked
|
< Transfer-Encoding: chunked
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
* Connection #0 to host localhost left intact
|
* Connection #0 to host localhost left intact
|
||||||
<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>%
|
<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>%
|
||||||
@ -613,7 +613,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_absolute_path_static_handler'
|
|||||||
< Content-Type: text/html; charset=UTF-8
|
< Content-Type: text/html; charset=UTF-8
|
||||||
< Transfer-Encoding: chunked
|
< Transfer-Encoding: chunked
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
<html><body>Absolute Path File</body></html>
|
<html><body>Absolute Path File</body></html>
|
||||||
* Connection #0 to host localhost left intact
|
* Connection #0 to host localhost left intact
|
||||||
@ -632,7 +632,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_relative_path_static_handler'
|
|||||||
< Content-Type: text/html; charset=UTF-8
|
< Content-Type: text/html; charset=UTF-8
|
||||||
< Transfer-Encoding: chunked
|
< Transfer-Encoding: chunked
|
||||||
< Keep-Alive: timeout=3
|
< Keep-Alive: timeout=3
|
||||||
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
|
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","peak_memory_usage":"0"}
|
||||||
<
|
<
|
||||||
<html><body>Relative Path File</body></html>
|
<html><body>Relative Path File</body></html>
|
||||||
* Connection #0 to host localhost left intact
|
* Connection #0 to host localhost left intact
|
||||||
|
@ -812,6 +812,11 @@ bool Client::processWithFuzzing(const String & full_query)
|
|||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
if (!ast_to_process)
|
||||||
|
fmt::print(stderr,
|
||||||
|
"Error while forming new query: {}\n",
|
||||||
|
getCurrentExceptionMessage(true));
|
||||||
|
|
||||||
// Some functions (e.g. protocol parsers) don't throw, but
|
// Some functions (e.g. protocol parsers) don't throw, but
|
||||||
// set last_exception instead, so we'll also do it here for
|
// set last_exception instead, so we'll also do it here for
|
||||||
// uniformity.
|
// uniformity.
|
||||||
|
@ -65,6 +65,7 @@ if (BUILD_STANDALONE_KEEPER)
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Server/PrometheusRequestHandler.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Server/PrometheusRequestHandler.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Server/PrometheusMetricsWriter.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Server/PrometheusMetricsWriter.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Server/waitServersToFinish.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Server/waitServersToFinish.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Server/ServerType.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Server/HTTPRequestHandlerFactoryMain.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Server/HTTPRequestHandlerFactoryMain.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Server/HTTP/HTTPServer.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Server/HTTP/HTTPServer.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Server/HTTP/ReadHeaders.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Server/HTTP/ReadHeaders.cpp
|
||||||
@ -80,6 +81,7 @@ if (BUILD_STANDALONE_KEEPER)
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Compression/CompressedReadBuffer.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Compression/CompressedReadBuffer.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Compression/CompressedReadBufferFromFile.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Compression/CompressedReadBufferFromFile.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Compression/CompressedWriteBuffer.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Compression/CompressedWriteBuffer.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Compression/CompressionCodecEncrypted.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Compression/CompressionCodecLZ4.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Compression/CompressionCodecLZ4.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Compression/CompressionCodecMultiple.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Compression/CompressionCodecMultiple.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Compression/CompressionCodecNone.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/../../src/Compression/CompressionCodecNone.cpp
|
||||||
|
@ -747,6 +747,7 @@ try
|
|||||||
|
|
||||||
std::lock_guard lock(servers_lock);
|
std::lock_guard lock(servers_lock);
|
||||||
metrics.reserve(servers_to_start_before_tables.size() + servers.size());
|
metrics.reserve(servers_to_start_before_tables.size() + servers.size());
|
||||||
|
|
||||||
for (const auto & server : servers_to_start_before_tables)
|
for (const auto & server : servers_to_start_before_tables)
|
||||||
metrics.emplace_back(ProtocolServerMetrics{server.getPortName(), server.currentThreads()});
|
metrics.emplace_back(ProtocolServerMetrics{server.getPortName(), server.currentThreads()});
|
||||||
|
|
||||||
@ -1456,6 +1457,24 @@ try
|
|||||||
access_control.reload(AccessControl::ReloadMode::USERS_CONFIG_ONLY);
|
access_control.reload(AccessControl::ReloadMode::USERS_CONFIG_ONLY);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
global_context->setStopServersCallback([&](const ServerType & server_type)
|
||||||
|
{
|
||||||
|
stopServers(servers, server_type);
|
||||||
|
});
|
||||||
|
|
||||||
|
global_context->setStartServersCallback([&](const ServerType & server_type)
|
||||||
|
{
|
||||||
|
createServers(
|
||||||
|
config(),
|
||||||
|
listen_hosts,
|
||||||
|
listen_try,
|
||||||
|
server_pool,
|
||||||
|
async_metrics,
|
||||||
|
servers,
|
||||||
|
/* start_servers= */ true,
|
||||||
|
server_type);
|
||||||
|
});
|
||||||
|
|
||||||
/// Limit on total number of concurrently executed queries.
|
/// Limit on total number of concurrently executed queries.
|
||||||
global_context->getProcessList().setMaxSize(server_settings.max_concurrent_queries);
|
global_context->getProcessList().setMaxSize(server_settings.max_concurrent_queries);
|
||||||
|
|
||||||
@ -1476,16 +1495,18 @@ try
|
|||||||
|
|
||||||
/// Load global settings from default_profile and system_profile.
|
/// Load global settings from default_profile and system_profile.
|
||||||
global_context->setDefaultProfiles(config());
|
global_context->setDefaultProfiles(config());
|
||||||
const Settings & settings = global_context->getSettingsRef();
|
|
||||||
|
|
||||||
/// Initialize background executors after we load default_profile config.
|
/// Initialize background executors after we load default_profile config.
|
||||||
/// This is needed to load proper values of background_pool_size etc.
|
/// This is needed to load proper values of background_pool_size etc.
|
||||||
global_context->initializeBackgroundExecutorsIfNeeded();
|
global_context->initializeBackgroundExecutorsIfNeeded();
|
||||||
|
|
||||||
if (settings.async_insert_threads)
|
if (server_settings.async_insert_threads)
|
||||||
|
{
|
||||||
global_context->setAsynchronousInsertQueue(std::make_shared<AsynchronousInsertQueue>(
|
global_context->setAsynchronousInsertQueue(std::make_shared<AsynchronousInsertQueue>(
|
||||||
global_context,
|
global_context,
|
||||||
settings.async_insert_threads));
|
server_settings.async_insert_threads,
|
||||||
|
server_settings.async_insert_queue_flush_on_shutdown));
|
||||||
|
}
|
||||||
|
|
||||||
size_t mark_cache_size = server_settings.mark_cache_size;
|
size_t mark_cache_size = server_settings.mark_cache_size;
|
||||||
String mark_cache_policy = server_settings.mark_cache_policy;
|
String mark_cache_policy = server_settings.mark_cache_policy;
|
||||||
@ -1995,7 +2016,8 @@ void Server::createServers(
|
|||||||
Poco::ThreadPool & server_pool,
|
Poco::ThreadPool & server_pool,
|
||||||
AsynchronousMetrics & async_metrics,
|
AsynchronousMetrics & async_metrics,
|
||||||
std::vector<ProtocolServerAdapter> & servers,
|
std::vector<ProtocolServerAdapter> & servers,
|
||||||
bool start_servers)
|
bool start_servers,
|
||||||
|
const ServerType & server_type)
|
||||||
{
|
{
|
||||||
const Settings & settings = global_context->getSettingsRef();
|
const Settings & settings = global_context->getSettingsRef();
|
||||||
|
|
||||||
@ -2009,6 +2031,9 @@ void Server::createServers(
|
|||||||
|
|
||||||
for (const auto & protocol : protocols)
|
for (const auto & protocol : protocols)
|
||||||
{
|
{
|
||||||
|
if (!server_type.shouldStart(ServerType::Type::CUSTOM, protocol))
|
||||||
|
continue;
|
||||||
|
|
||||||
std::vector<std::string> hosts;
|
std::vector<std::string> hosts;
|
||||||
if (config.has("protocols." + protocol + ".host"))
|
if (config.has("protocols." + protocol + ".host"))
|
||||||
hosts.push_back(config.getString("protocols." + protocol + ".host"));
|
hosts.push_back(config.getString("protocols." + protocol + ".host"));
|
||||||
@ -2054,9 +2079,13 @@ void Server::createServers(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto & listen_host : listen_hosts)
|
for (const auto & listen_host : listen_hosts)
|
||||||
|
{
|
||||||
|
const char * port_name;
|
||||||
|
|
||||||
|
if (server_type.shouldStart(ServerType::Type::HTTP))
|
||||||
{
|
{
|
||||||
/// HTTP
|
/// HTTP
|
||||||
const char * port_name = "http_port";
|
port_name = "http_port";
|
||||||
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
||||||
{
|
{
|
||||||
Poco::Net::ServerSocket socket;
|
Poco::Net::ServerSocket socket;
|
||||||
@ -2071,7 +2100,10 @@ void Server::createServers(
|
|||||||
std::make_unique<HTTPServer>(
|
std::make_unique<HTTPServer>(
|
||||||
httpContext(), createHandlerFactory(*this, config, async_metrics, "HTTPHandler-factory"), server_pool, socket, http_params));
|
httpContext(), createHandlerFactory(*this, config, async_metrics, "HTTPHandler-factory"), server_pool, socket, http_params));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server_type.shouldStart(ServerType::Type::HTTPS))
|
||||||
|
{
|
||||||
/// HTTPS
|
/// HTTPS
|
||||||
port_name = "https_port";
|
port_name = "https_port";
|
||||||
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
||||||
@ -2092,7 +2124,10 @@ void Server::createServers(
|
|||||||
throw Exception(ErrorCodes::SUPPORT_IS_DISABLED, "HTTPS protocol is disabled because Poco library was built without NetSSL support.");
|
throw Exception(ErrorCodes::SUPPORT_IS_DISABLED, "HTTPS protocol is disabled because Poco library was built without NetSSL support.");
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server_type.shouldStart(ServerType::Type::TCP))
|
||||||
|
{
|
||||||
/// TCP
|
/// TCP
|
||||||
port_name = "tcp_port";
|
port_name = "tcp_port";
|
||||||
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
||||||
@ -2111,7 +2146,10 @@ void Server::createServers(
|
|||||||
socket,
|
socket,
|
||||||
new Poco::Net::TCPServerParams));
|
new Poco::Net::TCPServerParams));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server_type.shouldStart(ServerType::Type::TCP_WITH_PROXY))
|
||||||
|
{
|
||||||
/// TCP with PROXY protocol, see https://github.com/wolfeidau/proxyv2/blob/master/docs/proxy-protocol.txt
|
/// TCP with PROXY protocol, see https://github.com/wolfeidau/proxyv2/blob/master/docs/proxy-protocol.txt
|
||||||
port_name = "tcp_with_proxy_port";
|
port_name = "tcp_with_proxy_port";
|
||||||
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
||||||
@ -2130,7 +2168,10 @@ void Server::createServers(
|
|||||||
socket,
|
socket,
|
||||||
new Poco::Net::TCPServerParams));
|
new Poco::Net::TCPServerParams));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server_type.shouldStart(ServerType::Type::TCP_SECURE))
|
||||||
|
{
|
||||||
/// TCP with SSL
|
/// TCP with SSL
|
||||||
port_name = "tcp_port_secure";
|
port_name = "tcp_port_secure";
|
||||||
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
||||||
@ -2154,7 +2195,10 @@ void Server::createServers(
|
|||||||
throw Exception(ErrorCodes::SUPPORT_IS_DISABLED, "SSL support for TCP protocol is disabled because Poco library was built without NetSSL support.");
|
throw Exception(ErrorCodes::SUPPORT_IS_DISABLED, "SSL support for TCP protocol is disabled because Poco library was built without NetSSL support.");
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server_type.shouldStart(ServerType::Type::MYSQL))
|
||||||
|
{
|
||||||
port_name = "mysql_port";
|
port_name = "mysql_port";
|
||||||
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
||||||
{
|
{
|
||||||
@ -2168,7 +2212,10 @@ void Server::createServers(
|
|||||||
"MySQL compatibility protocol: " + address.toString(),
|
"MySQL compatibility protocol: " + address.toString(),
|
||||||
std::make_unique<TCPServer>(new MySQLHandlerFactory(*this), server_pool, socket, new Poco::Net::TCPServerParams));
|
std::make_unique<TCPServer>(new MySQLHandlerFactory(*this), server_pool, socket, new Poco::Net::TCPServerParams));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server_type.shouldStart(ServerType::Type::POSTGRESQL))
|
||||||
|
{
|
||||||
port_name = "postgresql_port";
|
port_name = "postgresql_port";
|
||||||
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
||||||
{
|
{
|
||||||
@ -2182,8 +2229,11 @@ void Server::createServers(
|
|||||||
"PostgreSQL compatibility protocol: " + address.toString(),
|
"PostgreSQL compatibility protocol: " + address.toString(),
|
||||||
std::make_unique<TCPServer>(new PostgreSQLHandlerFactory(*this), server_pool, socket, new Poco::Net::TCPServerParams));
|
std::make_unique<TCPServer>(new PostgreSQLHandlerFactory(*this), server_pool, socket, new Poco::Net::TCPServerParams));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#if USE_GRPC
|
#if USE_GRPC
|
||||||
|
if (server_type.shouldStart(ServerType::Type::GRPC))
|
||||||
|
{
|
||||||
port_name = "grpc_port";
|
port_name = "grpc_port";
|
||||||
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
||||||
{
|
{
|
||||||
@ -2194,8 +2244,10 @@ void Server::createServers(
|
|||||||
"gRPC protocol: " + server_address.toString(),
|
"gRPC protocol: " + server_address.toString(),
|
||||||
std::make_unique<GRPCServer>(*this, makeSocketAddress(listen_host, port, &logger())));
|
std::make_unique<GRPCServer>(*this, makeSocketAddress(listen_host, port, &logger())));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (server_type.shouldStart(ServerType::Type::PROMETHEUS))
|
||||||
|
{
|
||||||
/// Prometheus (if defined and not setup yet with http_port)
|
/// Prometheus (if defined and not setup yet with http_port)
|
||||||
port_name = "prometheus.port";
|
port_name = "prometheus.port";
|
||||||
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
||||||
@ -2213,6 +2265,7 @@ void Server::createServers(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Server::createInterserverServers(
|
void Server::createInterserverServers(
|
||||||
Poco::Util::AbstractConfiguration & config,
|
Poco::Util::AbstractConfiguration & config,
|
||||||
@ -2221,7 +2274,8 @@ void Server::createInterserverServers(
|
|||||||
Poco::ThreadPool & server_pool,
|
Poco::ThreadPool & server_pool,
|
||||||
AsynchronousMetrics & async_metrics,
|
AsynchronousMetrics & async_metrics,
|
||||||
std::vector<ProtocolServerAdapter> & servers,
|
std::vector<ProtocolServerAdapter> & servers,
|
||||||
bool start_servers)
|
bool start_servers,
|
||||||
|
const ServerType & server_type)
|
||||||
{
|
{
|
||||||
const Settings & settings = global_context->getSettingsRef();
|
const Settings & settings = global_context->getSettingsRef();
|
||||||
|
|
||||||
@ -2232,9 +2286,13 @@ void Server::createInterserverServers(
|
|||||||
|
|
||||||
/// Now iterate over interserver_listen_hosts
|
/// Now iterate over interserver_listen_hosts
|
||||||
for (const auto & interserver_listen_host : interserver_listen_hosts)
|
for (const auto & interserver_listen_host : interserver_listen_hosts)
|
||||||
|
{
|
||||||
|
const char * port_name;
|
||||||
|
|
||||||
|
if (server_type.shouldStart(ServerType::Type::INTERSERVER_HTTP))
|
||||||
{
|
{
|
||||||
/// Interserver IO HTTP
|
/// Interserver IO HTTP
|
||||||
const char * port_name = "interserver_http_port";
|
port_name = "interserver_http_port";
|
||||||
createServer(config, interserver_listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
createServer(config, interserver_listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
||||||
{
|
{
|
||||||
Poco::Net::ServerSocket socket;
|
Poco::Net::ServerSocket socket;
|
||||||
@ -2252,7 +2310,10 @@ void Server::createInterserverServers(
|
|||||||
socket,
|
socket,
|
||||||
http_params));
|
http_params));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server_type.shouldStart(ServerType::Type::INTERSERVER_HTTPS))
|
||||||
|
{
|
||||||
port_name = "interserver_https_port";
|
port_name = "interserver_https_port";
|
||||||
createServer(config, interserver_listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
createServer(config, interserver_listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
|
||||||
{
|
{
|
||||||
@ -2278,6 +2339,44 @@ void Server::createInterserverServers(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::stopServers(
|
||||||
|
std::vector<ProtocolServerAdapter> & servers,
|
||||||
|
const ServerType & server_type
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
Poco::Logger * log = &logger();
|
||||||
|
|
||||||
|
/// Remove servers once all their connections are closed
|
||||||
|
auto check_server = [&log](const char prefix[], auto & server)
|
||||||
|
{
|
||||||
|
if (!server.isStopping())
|
||||||
|
return false;
|
||||||
|
size_t current_connections = server.currentConnections();
|
||||||
|
LOG_DEBUG(log, "Server {}{}: {} ({} connections)",
|
||||||
|
server.getDescription(),
|
||||||
|
prefix,
|
||||||
|
!current_connections ? "finished" : "waiting",
|
||||||
|
current_connections);
|
||||||
|
return !current_connections;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::erase_if(servers, std::bind_front(check_server, " (from one of previous remove)"));
|
||||||
|
|
||||||
|
for (auto & server : servers)
|
||||||
|
{
|
||||||
|
if (!server.isStopping())
|
||||||
|
{
|
||||||
|
const std::string server_port_name = server.getPortName();
|
||||||
|
|
||||||
|
if (server_type.shouldStop(server_port_name))
|
||||||
|
server.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::erase_if(servers, std::bind_front(check_server, ""));
|
||||||
|
}
|
||||||
|
|
||||||
void Server::updateServers(
|
void Server::updateServers(
|
||||||
Poco::Util::AbstractConfiguration & config,
|
Poco::Util::AbstractConfiguration & config,
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
#include <Server/IServer.h>
|
#include <Server/IServer.h>
|
||||||
|
|
||||||
#include <Daemon/BaseDaemon.h>
|
#include <Daemon/BaseDaemon.h>
|
||||||
#include "Server/HTTP/HTTPContext.h"
|
#include <Server/HTTP/HTTPContext.h>
|
||||||
#include <Server/TCPProtocolStackFactory.h>
|
#include <Server/TCPProtocolStackFactory.h>
|
||||||
|
#include <Server/ServerType.h>
|
||||||
#include <Poco/Net/HTTPServerParams.h>
|
#include <Poco/Net/HTTPServerParams.h>
|
||||||
|
|
||||||
/** Server provides three interfaces:
|
/** Server provides three interfaces:
|
||||||
@ -106,7 +107,8 @@ private:
|
|||||||
Poco::ThreadPool & server_pool,
|
Poco::ThreadPool & server_pool,
|
||||||
AsynchronousMetrics & async_metrics,
|
AsynchronousMetrics & async_metrics,
|
||||||
std::vector<ProtocolServerAdapter> & servers,
|
std::vector<ProtocolServerAdapter> & servers,
|
||||||
bool start_servers = false);
|
bool start_servers = false,
|
||||||
|
const ServerType & server_type = ServerType(ServerType::Type::QUERIES_ALL));
|
||||||
|
|
||||||
void createInterserverServers(
|
void createInterserverServers(
|
||||||
Poco::Util::AbstractConfiguration & config,
|
Poco::Util::AbstractConfiguration & config,
|
||||||
@ -115,7 +117,8 @@ private:
|
|||||||
Poco::ThreadPool & server_pool,
|
Poco::ThreadPool & server_pool,
|
||||||
AsynchronousMetrics & async_metrics,
|
AsynchronousMetrics & async_metrics,
|
||||||
std::vector<ProtocolServerAdapter> & servers,
|
std::vector<ProtocolServerAdapter> & servers,
|
||||||
bool start_servers = false);
|
bool start_servers = false,
|
||||||
|
const ServerType & server_type = ServerType(ServerType::Type::QUERIES_ALL));
|
||||||
|
|
||||||
void updateServers(
|
void updateServers(
|
||||||
Poco::Util::AbstractConfiguration & config,
|
Poco::Util::AbstractConfiguration & config,
|
||||||
@ -123,6 +126,11 @@ private:
|
|||||||
AsynchronousMetrics & async_metrics,
|
AsynchronousMetrics & async_metrics,
|
||||||
std::vector<ProtocolServerAdapter> & servers,
|
std::vector<ProtocolServerAdapter> & servers,
|
||||||
std::vector<ProtocolServerAdapter> & servers_to_start_before_tables);
|
std::vector<ProtocolServerAdapter> & servers_to_start_before_tables);
|
||||||
|
|
||||||
|
void stopServers(
|
||||||
|
std::vector<ProtocolServerAdapter> & servers,
|
||||||
|
const ServerType & server_type
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -182,10 +182,12 @@ enum class AccessType
|
|||||||
M(SYSTEM_SYNC_FILE_CACHE, "SYNC FILE CACHE", GLOBAL, SYSTEM) \
|
M(SYSTEM_SYNC_FILE_CACHE, "SYNC FILE CACHE", GLOBAL, SYSTEM) \
|
||||||
M(SYSTEM_FLUSH_DISTRIBUTED, "FLUSH DISTRIBUTED", TABLE, SYSTEM_FLUSH) \
|
M(SYSTEM_FLUSH_DISTRIBUTED, "FLUSH DISTRIBUTED", TABLE, SYSTEM_FLUSH) \
|
||||||
M(SYSTEM_FLUSH_LOGS, "FLUSH LOGS", GLOBAL, SYSTEM_FLUSH) \
|
M(SYSTEM_FLUSH_LOGS, "FLUSH LOGS", GLOBAL, SYSTEM_FLUSH) \
|
||||||
|
M(SYSTEM_FLUSH_ASYNC_INSERT_QUEUE, "FLUSH ASYNC INSERT QUEUE", GLOBAL, SYSTEM_FLUSH) \
|
||||||
M(SYSTEM_FLUSH, "", GROUP, SYSTEM) \
|
M(SYSTEM_FLUSH, "", GROUP, SYSTEM) \
|
||||||
M(SYSTEM_THREAD_FUZZER, "SYSTEM START THREAD FUZZER, SYSTEM STOP THREAD FUZZER, START THREAD FUZZER, STOP THREAD FUZZER", GLOBAL, SYSTEM) \
|
M(SYSTEM_THREAD_FUZZER, "SYSTEM START THREAD FUZZER, SYSTEM STOP THREAD FUZZER, START THREAD FUZZER, STOP THREAD FUZZER", GLOBAL, SYSTEM) \
|
||||||
M(SYSTEM_UNFREEZE, "SYSTEM UNFREEZE", GLOBAL, SYSTEM) \
|
M(SYSTEM_UNFREEZE, "SYSTEM UNFREEZE", GLOBAL, SYSTEM) \
|
||||||
M(SYSTEM_FAILPOINT, "SYSTEM ENABLE FAILPOINT, SYSTEM DISABLE FAILPOINT", GLOBAL, SYSTEM) \
|
M(SYSTEM_FAILPOINT, "SYSTEM ENABLE FAILPOINT, SYSTEM DISABLE FAILPOINT", GLOBAL, SYSTEM) \
|
||||||
|
M(SYSTEM_LISTEN, "SYSTEM START LISTEN, SYSTEM STOP LISTEN", GLOBAL, SYSTEM) \
|
||||||
M(SYSTEM, "", GROUP, ALL) /* allows to execute SYSTEM {SHUTDOWN|RELOAD CONFIG|...} */ \
|
M(SYSTEM, "", GROUP, ALL) /* allows to execute SYSTEM {SHUTDOWN|RELOAD CONFIG|...} */ \
|
||||||
\
|
\
|
||||||
M(dictGet, "dictHas, dictGetHierarchy, dictIsIn", DICTIONARY, ALL) /* allows to execute functions dictGet(), dictHas(), dictGetHierarchy(), dictIsIn() */\
|
M(dictGet, "dictHas, dictGetHierarchy, dictIsIn", DICTIONARY, ALL) /* allows to execute functions dictGet(), dictHas(), dictGetHierarchy(), dictIsIn() */\
|
||||||
|
@ -49,6 +49,7 @@ void registerAggregateFunctionsAny(AggregateFunctionFactory & factory)
|
|||||||
AggregateFunctionProperties properties = { .returns_default_when_only_null = false, .is_order_dependent = true };
|
AggregateFunctionProperties properties = { .returns_default_when_only_null = false, .is_order_dependent = true };
|
||||||
|
|
||||||
factory.registerFunction("any", { createAggregateFunctionAny, properties });
|
factory.registerFunction("any", { createAggregateFunctionAny, properties });
|
||||||
|
factory.registerAlias("any_value", "any", AggregateFunctionFactory::CaseInsensitive);
|
||||||
factory.registerFunction("anyLast", { createAggregateFunctionAnyLast, properties });
|
factory.registerFunction("anyLast", { createAggregateFunctionAnyLast, properties });
|
||||||
factory.registerFunction("anyHeavy", { createAggregateFunctionAnyHeavy, properties });
|
factory.registerFunction("anyHeavy", { createAggregateFunctionAnyHeavy, properties });
|
||||||
|
|
||||||
|
@ -29,6 +29,10 @@
|
|||||||
#include <AggregateFunctions/UniqVariadicHash.h>
|
#include <AggregateFunctions/UniqVariadicHash.h>
|
||||||
#include <AggregateFunctions/UniquesHashSet.h>
|
#include <AggregateFunctions/UniquesHashSet.h>
|
||||||
|
|
||||||
|
namespace ErrorCodes
|
||||||
|
{
|
||||||
|
extern const int NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
@ -42,6 +46,7 @@ struct AggregateFunctionUniqUniquesHashSetData
|
|||||||
Set set;
|
Set set;
|
||||||
|
|
||||||
constexpr static bool is_able_to_parallelize_merge = false;
|
constexpr static bool is_able_to_parallelize_merge = false;
|
||||||
|
constexpr static bool is_parallelize_merge_prepare_needed = false;
|
||||||
constexpr static bool is_variadic = false;
|
constexpr static bool is_variadic = false;
|
||||||
|
|
||||||
static String getName() { return "uniq"; }
|
static String getName() { return "uniq"; }
|
||||||
@ -55,6 +60,7 @@ struct AggregateFunctionUniqUniquesHashSetDataForVariadic
|
|||||||
Set set;
|
Set set;
|
||||||
|
|
||||||
constexpr static bool is_able_to_parallelize_merge = false;
|
constexpr static bool is_able_to_parallelize_merge = false;
|
||||||
|
constexpr static bool is_parallelize_merge_prepare_needed = false;
|
||||||
constexpr static bool is_variadic = true;
|
constexpr static bool is_variadic = true;
|
||||||
constexpr static bool is_exact = is_exact_;
|
constexpr static bool is_exact = is_exact_;
|
||||||
constexpr static bool argument_is_tuple = argument_is_tuple_;
|
constexpr static bool argument_is_tuple = argument_is_tuple_;
|
||||||
@ -72,6 +78,7 @@ struct AggregateFunctionUniqHLL12Data
|
|||||||
Set set;
|
Set set;
|
||||||
|
|
||||||
constexpr static bool is_able_to_parallelize_merge = is_able_to_parallelize_merge_;
|
constexpr static bool is_able_to_parallelize_merge = is_able_to_parallelize_merge_;
|
||||||
|
constexpr static bool is_parallelize_merge_prepare_needed = false;
|
||||||
constexpr static bool is_variadic = false;
|
constexpr static bool is_variadic = false;
|
||||||
|
|
||||||
static String getName() { return "uniqHLL12"; }
|
static String getName() { return "uniqHLL12"; }
|
||||||
@ -84,6 +91,7 @@ struct AggregateFunctionUniqHLL12Data<String, false>
|
|||||||
Set set;
|
Set set;
|
||||||
|
|
||||||
constexpr static bool is_able_to_parallelize_merge = false;
|
constexpr static bool is_able_to_parallelize_merge = false;
|
||||||
|
constexpr static bool is_parallelize_merge_prepare_needed = false;
|
||||||
constexpr static bool is_variadic = false;
|
constexpr static bool is_variadic = false;
|
||||||
|
|
||||||
static String getName() { return "uniqHLL12"; }
|
static String getName() { return "uniqHLL12"; }
|
||||||
@ -96,6 +104,7 @@ struct AggregateFunctionUniqHLL12Data<UUID, false>
|
|||||||
Set set;
|
Set set;
|
||||||
|
|
||||||
constexpr static bool is_able_to_parallelize_merge = false;
|
constexpr static bool is_able_to_parallelize_merge = false;
|
||||||
|
constexpr static bool is_parallelize_merge_prepare_needed = false;
|
||||||
constexpr static bool is_variadic = false;
|
constexpr static bool is_variadic = false;
|
||||||
|
|
||||||
static String getName() { return "uniqHLL12"; }
|
static String getName() { return "uniqHLL12"; }
|
||||||
@ -108,6 +117,7 @@ struct AggregateFunctionUniqHLL12Data<IPv6, false>
|
|||||||
Set set;
|
Set set;
|
||||||
|
|
||||||
constexpr static bool is_able_to_parallelize_merge = false;
|
constexpr static bool is_able_to_parallelize_merge = false;
|
||||||
|
constexpr static bool is_parallelize_merge_prepare_needed = false;
|
||||||
constexpr static bool is_variadic = false;
|
constexpr static bool is_variadic = false;
|
||||||
|
|
||||||
static String getName() { return "uniqHLL12"; }
|
static String getName() { return "uniqHLL12"; }
|
||||||
@ -120,6 +130,7 @@ struct AggregateFunctionUniqHLL12DataForVariadic
|
|||||||
Set set;
|
Set set;
|
||||||
|
|
||||||
constexpr static bool is_able_to_parallelize_merge = is_able_to_parallelize_merge_;
|
constexpr static bool is_able_to_parallelize_merge = is_able_to_parallelize_merge_;
|
||||||
|
constexpr static bool is_parallelize_merge_prepare_needed = false;
|
||||||
constexpr static bool is_variadic = true;
|
constexpr static bool is_variadic = true;
|
||||||
constexpr static bool is_exact = is_exact_;
|
constexpr static bool is_exact = is_exact_;
|
||||||
constexpr static bool argument_is_tuple = argument_is_tuple_;
|
constexpr static bool argument_is_tuple = argument_is_tuple_;
|
||||||
@ -143,6 +154,7 @@ struct AggregateFunctionUniqExactData
|
|||||||
Set set;
|
Set set;
|
||||||
|
|
||||||
constexpr static bool is_able_to_parallelize_merge = is_able_to_parallelize_merge_;
|
constexpr static bool is_able_to_parallelize_merge = is_able_to_parallelize_merge_;
|
||||||
|
constexpr static bool is_parallelize_merge_prepare_needed = true;
|
||||||
constexpr static bool is_variadic = false;
|
constexpr static bool is_variadic = false;
|
||||||
|
|
||||||
static String getName() { return "uniqExact"; }
|
static String getName() { return "uniqExact"; }
|
||||||
@ -162,6 +174,7 @@ struct AggregateFunctionUniqExactData<String, is_able_to_parallelize_merge_>
|
|||||||
Set set;
|
Set set;
|
||||||
|
|
||||||
constexpr static bool is_able_to_parallelize_merge = is_able_to_parallelize_merge_;
|
constexpr static bool is_able_to_parallelize_merge = is_able_to_parallelize_merge_;
|
||||||
|
constexpr static bool is_parallelize_merge_prepare_needed = true;
|
||||||
constexpr static bool is_variadic = false;
|
constexpr static bool is_variadic = false;
|
||||||
|
|
||||||
static String getName() { return "uniqExact"; }
|
static String getName() { return "uniqExact"; }
|
||||||
@ -181,6 +194,7 @@ struct AggregateFunctionUniqExactData<IPv6, is_able_to_parallelize_merge_>
|
|||||||
Set set;
|
Set set;
|
||||||
|
|
||||||
constexpr static bool is_able_to_parallelize_merge = is_able_to_parallelize_merge_;
|
constexpr static bool is_able_to_parallelize_merge = is_able_to_parallelize_merge_;
|
||||||
|
constexpr static bool is_parallelize_merge_prepare_needed = true;
|
||||||
constexpr static bool is_variadic = false;
|
constexpr static bool is_variadic = false;
|
||||||
|
|
||||||
static String getName() { return "uniqExact"; }
|
static String getName() { return "uniqExact"; }
|
||||||
@ -190,6 +204,7 @@ template <bool is_exact_, bool argument_is_tuple_, bool is_able_to_parallelize_m
|
|||||||
struct AggregateFunctionUniqExactDataForVariadic : AggregateFunctionUniqExactData<String, is_able_to_parallelize_merge_>
|
struct AggregateFunctionUniqExactDataForVariadic : AggregateFunctionUniqExactData<String, is_able_to_parallelize_merge_>
|
||||||
{
|
{
|
||||||
constexpr static bool is_able_to_parallelize_merge = is_able_to_parallelize_merge_;
|
constexpr static bool is_able_to_parallelize_merge = is_able_to_parallelize_merge_;
|
||||||
|
constexpr static bool is_parallelize_merge_prepare_needed = true;
|
||||||
constexpr static bool is_variadic = true;
|
constexpr static bool is_variadic = true;
|
||||||
constexpr static bool is_exact = is_exact_;
|
constexpr static bool is_exact = is_exact_;
|
||||||
constexpr static bool argument_is_tuple = argument_is_tuple_;
|
constexpr static bool argument_is_tuple = argument_is_tuple_;
|
||||||
@ -204,6 +219,7 @@ struct AggregateFunctionUniqThetaData
|
|||||||
Set set;
|
Set set;
|
||||||
|
|
||||||
constexpr static bool is_able_to_parallelize_merge = false;
|
constexpr static bool is_able_to_parallelize_merge = false;
|
||||||
|
constexpr static bool is_parallelize_merge_prepare_needed = false;
|
||||||
constexpr static bool is_variadic = false;
|
constexpr static bool is_variadic = false;
|
||||||
|
|
||||||
static String getName() { return "uniqTheta"; }
|
static String getName() { return "uniqTheta"; }
|
||||||
@ -213,6 +229,7 @@ template <bool is_exact_, bool argument_is_tuple_>
|
|||||||
struct AggregateFunctionUniqThetaDataForVariadic : AggregateFunctionUniqThetaData
|
struct AggregateFunctionUniqThetaDataForVariadic : AggregateFunctionUniqThetaData
|
||||||
{
|
{
|
||||||
constexpr static bool is_able_to_parallelize_merge = false;
|
constexpr static bool is_able_to_parallelize_merge = false;
|
||||||
|
constexpr static bool is_parallelize_merge_prepare_needed = false;
|
||||||
constexpr static bool is_variadic = true;
|
constexpr static bool is_variadic = true;
|
||||||
constexpr static bool is_exact = is_exact_;
|
constexpr static bool is_exact = is_exact_;
|
||||||
constexpr static bool argument_is_tuple = argument_is_tuple_;
|
constexpr static bool argument_is_tuple = argument_is_tuple_;
|
||||||
@ -384,8 +401,10 @@ template <typename T, typename Data>
|
|||||||
class AggregateFunctionUniq final : public IAggregateFunctionDataHelper<Data, AggregateFunctionUniq<T, Data>>
|
class AggregateFunctionUniq final : public IAggregateFunctionDataHelper<Data, AggregateFunctionUniq<T, Data>>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
using DataSet = typename Data::Set;
|
||||||
static constexpr size_t num_args = 1;
|
static constexpr size_t num_args = 1;
|
||||||
static constexpr bool is_able_to_parallelize_merge = Data::is_able_to_parallelize_merge;
|
static constexpr bool is_able_to_parallelize_merge = Data::is_able_to_parallelize_merge;
|
||||||
|
static constexpr bool is_parallelize_merge_prepare_needed = Data::is_parallelize_merge_prepare_needed;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AggregateFunctionUniq(const DataTypes & argument_types_)
|
explicit AggregateFunctionUniq(const DataTypes & argument_types_)
|
||||||
@ -439,6 +458,26 @@ public:
|
|||||||
detail::Adder<T, Data>::add(this->data(place), columns, num_args, row_begin, row_end, flags, null_map);
|
detail::Adder<T, Data>::add(this->data(place), columns, num_args, row_begin, row_end, flags, null_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isParallelizeMergePrepareNeeded() const override { return is_parallelize_merge_prepare_needed;}
|
||||||
|
|
||||||
|
void parallelizeMergePrepare(AggregateDataPtrs & places, ThreadPool & thread_pool) const override
|
||||||
|
{
|
||||||
|
if constexpr (is_parallelize_merge_prepare_needed)
|
||||||
|
{
|
||||||
|
std::vector<DataSet *> data_vec;
|
||||||
|
data_vec.resize(places.size());
|
||||||
|
|
||||||
|
for (unsigned long i = 0; i < data_vec.size(); i++)
|
||||||
|
data_vec[i] = &this->data(places[i]).set;
|
||||||
|
|
||||||
|
DataSet::parallelizeMergePrepare(data_vec, thread_pool);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "parallelizeMergePrepare() is only implemented when is_parallelize_merge_prepare_needed is true for {} ", getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void merge(AggregateDataPtr __restrict place, ConstAggregateDataPtr rhs, Arena *) const override
|
void merge(AggregateDataPtr __restrict place, ConstAggregateDataPtr rhs, Arena *) const override
|
||||||
{
|
{
|
||||||
this->data(place).set.merge(this->data(rhs).set);
|
this->data(place).set.merge(this->data(rhs).set);
|
||||||
|
@ -47,6 +47,7 @@ using DataTypePtr = std::shared_ptr<const IDataType>;
|
|||||||
using DataTypes = std::vector<DataTypePtr>;
|
using DataTypes = std::vector<DataTypePtr>;
|
||||||
|
|
||||||
using AggregateDataPtr = char *;
|
using AggregateDataPtr = char *;
|
||||||
|
using AggregateDataPtrs = std::vector<AggregateDataPtr>;
|
||||||
using ConstAggregateDataPtr = const char *;
|
using ConstAggregateDataPtr = const char *;
|
||||||
|
|
||||||
class IAggregateFunction;
|
class IAggregateFunction;
|
||||||
@ -148,6 +149,13 @@ public:
|
|||||||
/// Default values must be a the 0-th positions in columns.
|
/// Default values must be a the 0-th positions in columns.
|
||||||
virtual void addManyDefaults(AggregateDataPtr __restrict place, const IColumn ** columns, size_t length, Arena * arena) const = 0;
|
virtual void addManyDefaults(AggregateDataPtr __restrict place, const IColumn ** columns, size_t length, Arena * arena) const = 0;
|
||||||
|
|
||||||
|
virtual bool isParallelizeMergePrepareNeeded() const { return false; }
|
||||||
|
|
||||||
|
virtual void parallelizeMergePrepare(AggregateDataPtrs & /*places*/, ThreadPool & /*thread_pool*/) const
|
||||||
|
{
|
||||||
|
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "parallelizeMergePrepare() with thread pool parameter isn't implemented for {} ", getName());
|
||||||
|
}
|
||||||
|
|
||||||
/// Merges state (on which place points to) with other state of current aggregation function.
|
/// Merges state (on which place points to) with other state of current aggregation function.
|
||||||
virtual void merge(AggregateDataPtr __restrict place, ConstAggregateDataPtr rhs, Arena * arena) const = 0;
|
virtual void merge(AggregateDataPtr __restrict place, ConstAggregateDataPtr rhs, Arena * arena) const = 0;
|
||||||
|
|
||||||
|
@ -28,6 +28,57 @@ public:
|
|||||||
asTwoLevel().insert(std::forward<Arg>(arg));
|
asTwoLevel().insert(std::forward<Arg>(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// In merge, if one of the lhs and rhs is twolevelset and the other is singlelevelset, then the singlelevelset will need to convertToTwoLevel().
|
||||||
|
/// It's not in parallel and will cost extra large time if the thread_num is large.
|
||||||
|
/// This method will convert all the SingleLevelSet to TwoLevelSet in parallel if the hashsets are not all singlelevel or not all twolevel.
|
||||||
|
static void parallelizeMergePrepare(const std::vector<UniqExactSet *> & data_vec, ThreadPool & thread_pool)
|
||||||
|
{
|
||||||
|
unsigned long single_level_set_num = 0;
|
||||||
|
|
||||||
|
for (auto ele : data_vec)
|
||||||
|
{
|
||||||
|
if (ele->isSingleLevel())
|
||||||
|
single_level_set_num ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (single_level_set_num > 0 && single_level_set_num < data_vec.size())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto data_vec_atomic_index = std::make_shared<std::atomic_uint32_t>(0);
|
||||||
|
auto thread_func = [data_vec, data_vec_atomic_index, thread_group = CurrentThread::getGroup()]()
|
||||||
|
{
|
||||||
|
SCOPE_EXIT_SAFE(
|
||||||
|
if (thread_group)
|
||||||
|
CurrentThread::detachFromGroupIfNotDetached();
|
||||||
|
);
|
||||||
|
if (thread_group)
|
||||||
|
CurrentThread::attachToGroupIfDetached(thread_group);
|
||||||
|
|
||||||
|
setThreadName("UniqExaConvert");
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const auto i = data_vec_atomic_index->fetch_add(1);
|
||||||
|
if (i >= data_vec.size())
|
||||||
|
return;
|
||||||
|
if (data_vec[i]->isSingleLevel())
|
||||||
|
data_vec[i]->convertToTwoLevel();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (size_t i = 0; i < std::min<size_t>(thread_pool.getMaxThreads(), single_level_set_num); ++i)
|
||||||
|
thread_pool.scheduleOrThrowOnError(thread_func);
|
||||||
|
|
||||||
|
thread_pool.wait();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
thread_pool.wait();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto merge(const UniqExactSet & other, ThreadPool * thread_pool = nullptr)
|
auto merge(const UniqExactSet & other, ThreadPool * thread_pool = nullptr)
|
||||||
{
|
{
|
||||||
if (isSingleLevel() && other.isTwoLevel())
|
if (isSingleLevel() && other.isTwoLevel())
|
||||||
|
@ -267,6 +267,10 @@ add_object_library(clickhouse_processors_queryplan Processors/QueryPlan)
|
|||||||
add_object_library(clickhouse_processors_queryplan_optimizations Processors/QueryPlan/Optimizations)
|
add_object_library(clickhouse_processors_queryplan_optimizations Processors/QueryPlan/Optimizations)
|
||||||
add_object_library(clickhouse_user_defined_functions Functions/UserDefined)
|
add_object_library(clickhouse_user_defined_functions Functions/UserDefined)
|
||||||
|
|
||||||
|
if (USE_PARQUET)
|
||||||
|
add_object_library(clickhouse_processors_formats_impl_parquet Processors/Formats/Impl/Parquet)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (TARGET ch_contrib::nuraft)
|
if (TARGET ch_contrib::nuraft)
|
||||||
add_object_library(clickhouse_coordination Coordination)
|
add_object_library(clickhouse_coordination Coordination)
|
||||||
endif()
|
endif()
|
||||||
|
@ -1195,6 +1195,8 @@ void ClientBase::onProfileEvents(Block & block)
|
|||||||
thread_times[host_name].system_ms = value;
|
thread_times[host_name].system_ms = value;
|
||||||
else if (event_name == MemoryTracker::USAGE_EVENT_NAME)
|
else if (event_name == MemoryTracker::USAGE_EVENT_NAME)
|
||||||
thread_times[host_name].memory_usage = value;
|
thread_times[host_name].memory_usage = value;
|
||||||
|
else if (event_name == MemoryTracker::PEAK_USAGE_EVENT_NAME)
|
||||||
|
thread_times[host_name].peak_memory_usage = value;
|
||||||
}
|
}
|
||||||
progress_indication.updateThreadEventData(thread_times);
|
progress_indication.updateThreadEventData(thread_times);
|
||||||
|
|
||||||
|
@ -1,4 +1,26 @@
|
|||||||
#include "Allocator.h"
|
#include "Allocator.h"
|
||||||
|
|
||||||
template class Allocator<false>;
|
/** Keep definition of this constant in cpp file; otherwise its value
|
||||||
template class Allocator<true>;
|
* is inlined into allocator code making it impossible to override it
|
||||||
|
* in third-party code.
|
||||||
|
*
|
||||||
|
* Note: extern may seem redundant, but is actually needed due to bug in GCC.
|
||||||
|
* See also: https://gcc.gnu.org/legacy-ml/gcc-help/2017-12/msg00021.html
|
||||||
|
*/
|
||||||
|
#ifdef NDEBUG
|
||||||
|
__attribute__((__weak__)) extern const size_t MMAP_THRESHOLD = 128 * (1ULL << 20);
|
||||||
|
#else
|
||||||
|
/**
|
||||||
|
* In debug build, use small mmap threshold to reproduce more memory
|
||||||
|
* stomping bugs. Along with ASLR it will hopefully detect more issues than
|
||||||
|
* ASan. The program may fail due to the limit on number of memory mappings.
|
||||||
|
*
|
||||||
|
* Not too small to avoid too quick exhaust of memory mappings.
|
||||||
|
*/
|
||||||
|
__attribute__((__weak__)) extern const size_t MMAP_THRESHOLD = 16384;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template class Allocator<false, false>;
|
||||||
|
template class Allocator<true, false>;
|
||||||
|
template class Allocator<false, true>;
|
||||||
|
template class Allocator<true, true>;
|
||||||
|
@ -36,26 +36,51 @@
|
|||||||
#include <Common/Allocator_fwd.h>
|
#include <Common/Allocator_fwd.h>
|
||||||
|
|
||||||
|
|
||||||
|
/// Required for older Darwin builds, that lack definition of MAP_ANONYMOUS
|
||||||
|
#ifndef MAP_ANONYMOUS
|
||||||
|
#define MAP_ANONYMOUS MAP_ANON
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Many modern allocators (for example, tcmalloc) do not do a mremap for
|
||||||
|
* realloc, even in case of large enough chunks of memory. Although this allows
|
||||||
|
* you to increase performance and reduce memory consumption during realloc.
|
||||||
|
* To fix this, we do mremap manually if the chunk of memory is large enough.
|
||||||
|
* The threshold (64 MB) is chosen quite large, since changing the address
|
||||||
|
* space is very slow, especially in the case of a large number of threads. We
|
||||||
|
* expect that the set of operations mmap/something to do/mremap can only be
|
||||||
|
* performed about 1000 times per second.
|
||||||
|
*
|
||||||
|
* P.S. This is also required, because tcmalloc can not allocate a chunk of
|
||||||
|
* memory greater than 16 GB.
|
||||||
|
*
|
||||||
|
* P.P.S. Note that MMAP_THRESHOLD symbol is intentionally made weak. It allows
|
||||||
|
* to override it during linkage when using ClickHouse as a library in
|
||||||
|
* third-party applications which may already use own allocator doing mmaps
|
||||||
|
* in the implementation of alloc/realloc.
|
||||||
|
*/
|
||||||
|
extern const size_t MMAP_THRESHOLD;
|
||||||
|
|
||||||
static constexpr size_t MALLOC_MIN_ALIGNMENT = 8;
|
static constexpr size_t MALLOC_MIN_ALIGNMENT = 8;
|
||||||
|
|
||||||
|
namespace CurrentMetrics
|
||||||
|
{
|
||||||
|
extern const Metric MMappedAllocs;
|
||||||
|
extern const Metric MMappedAllocBytes;
|
||||||
|
}
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace ErrorCodes
|
namespace ErrorCodes
|
||||||
{
|
{
|
||||||
|
extern const int BAD_ARGUMENTS;
|
||||||
extern const int CANNOT_ALLOCATE_MEMORY;
|
extern const int CANNOT_ALLOCATE_MEMORY;
|
||||||
|
extern const int CANNOT_MUNMAP;
|
||||||
|
extern const int CANNOT_MREMAP;
|
||||||
extern const int LOGICAL_ERROR;
|
extern const int LOGICAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Previously there was a code which tried to use manual mmap and mremap (clickhouse_mremap.h) for large allocations/reallocations (64MB+).
|
|
||||||
* Most modern allocators (including jemalloc) don't use mremap, so the idea was to take advantage from mremap system call for large reallocs.
|
|
||||||
* Actually jemalloc had support for mremap, but it was intentionally removed from codebase https://github.com/jemalloc/jemalloc/commit/e2deab7a751c8080c2b2cdcfd7b11887332be1bb.
|
|
||||||
* Our performance tests also shows that without manual mmap/mremap/munmap clickhouse is overall faster for about 1-2% and up to 5-7x for some types of queries.
|
|
||||||
* That is why we don't do manuall mmap/mremap/munmap here and completely rely on jemalloc for allocations of any size.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Responsible for allocating / freeing memory. Used, for example, in PODArray, Arena.
|
/** Responsible for allocating / freeing memory. Used, for example, in PODArray, Arena.
|
||||||
* Also used in hash tables.
|
* Also used in hash tables.
|
||||||
* The interface is different from std::allocator
|
* The interface is different from std::allocator
|
||||||
@ -63,8 +88,10 @@ namespace ErrorCodes
|
|||||||
* - passing the size into the `free` method;
|
* - passing the size into the `free` method;
|
||||||
* - by the presence of the `alignment` argument;
|
* - by the presence of the `alignment` argument;
|
||||||
* - the possibility of zeroing memory (used in hash tables);
|
* - the possibility of zeroing memory (used in hash tables);
|
||||||
|
* - random hint address for mmap
|
||||||
|
* - mmap_threshold for using mmap less or more
|
||||||
*/
|
*/
|
||||||
template <bool clear_memory_>
|
template <bool clear_memory_, bool mmap_populate>
|
||||||
class Allocator
|
class Allocator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -82,7 +109,7 @@ public:
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
checkSize(size);
|
checkSize(size);
|
||||||
freeNoTrack(buf);
|
freeNoTrack(buf, size);
|
||||||
CurrentMemoryTracker::free(size);
|
CurrentMemoryTracker::free(size);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
@ -105,26 +132,49 @@ public:
|
|||||||
/// nothing to do.
|
/// nothing to do.
|
||||||
/// BTW, it's not possible to change alignment while doing realloc.
|
/// BTW, it's not possible to change alignment while doing realloc.
|
||||||
}
|
}
|
||||||
else if (alignment <= MALLOC_MIN_ALIGNMENT)
|
else if (old_size < MMAP_THRESHOLD && new_size < MMAP_THRESHOLD
|
||||||
|
&& alignment <= MALLOC_MIN_ALIGNMENT)
|
||||||
{
|
{
|
||||||
/// Resize malloc'd memory region with no special alignment requirement.
|
/// Resize malloc'd memory region with no special alignment requirement.
|
||||||
CurrentMemoryTracker::realloc(old_size, new_size);
|
CurrentMemoryTracker::realloc(old_size, new_size);
|
||||||
|
|
||||||
void * new_buf = ::realloc(buf, new_size);
|
void * new_buf = ::realloc(buf, new_size);
|
||||||
if (nullptr == new_buf)
|
if (nullptr == new_buf)
|
||||||
{
|
DB::throwFromErrno(fmt::format("Allocator: Cannot realloc from {} to {}.", ReadableSize(old_size), ReadableSize(new_size)), DB::ErrorCodes::CANNOT_ALLOCATE_MEMORY);
|
||||||
DB::throwFromErrno(
|
|
||||||
fmt::format("Allocator: Cannot realloc from {} to {}.", ReadableSize(old_size), ReadableSize(new_size)), DB::ErrorCodes::CANNOT_ALLOCATE_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = new_buf;
|
buf = new_buf;
|
||||||
if constexpr (clear_memory)
|
if constexpr (clear_memory)
|
||||||
if (new_size > old_size)
|
if (new_size > old_size)
|
||||||
memset(reinterpret_cast<char *>(buf) + old_size, 0, new_size - old_size);
|
memset(reinterpret_cast<char *>(buf) + old_size, 0, new_size - old_size);
|
||||||
}
|
}
|
||||||
|
else if (old_size >= MMAP_THRESHOLD && new_size >= MMAP_THRESHOLD)
|
||||||
|
{
|
||||||
|
/// Resize mmap'd memory region.
|
||||||
|
CurrentMemoryTracker::realloc(old_size, new_size);
|
||||||
|
|
||||||
|
// On apple and freebsd self-implemented mremap used (common/mremap.h)
|
||||||
|
buf = clickhouse_mremap(buf, old_size, new_size, MREMAP_MAYMOVE,
|
||||||
|
PROT_READ | PROT_WRITE, mmap_flags, -1, 0);
|
||||||
|
if (MAP_FAILED == buf)
|
||||||
|
DB::throwFromErrno(fmt::format("Allocator: Cannot mremap memory chunk from {} to {}.",
|
||||||
|
ReadableSize(old_size), ReadableSize(new_size)), DB::ErrorCodes::CANNOT_MREMAP);
|
||||||
|
|
||||||
|
/// No need for zero-fill, because mmap guarantees it.
|
||||||
|
}
|
||||||
|
else if (new_size < MMAP_THRESHOLD)
|
||||||
|
{
|
||||||
|
/// Small allocs that requires a copy. Assume there's enough memory in system. Call CurrentMemoryTracker once.
|
||||||
|
CurrentMemoryTracker::realloc(old_size, new_size);
|
||||||
|
|
||||||
|
void * new_buf = allocNoTrack(new_size, alignment);
|
||||||
|
memcpy(new_buf, buf, std::min(old_size, new_size));
|
||||||
|
freeNoTrack(buf, old_size);
|
||||||
|
buf = new_buf;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/// Big allocs that requires a copy. MemoryTracker is called inside 'alloc', 'free' methods.
|
/// Big allocs that requires a copy. MemoryTracker is called inside 'alloc', 'free' methods.
|
||||||
|
|
||||||
void * new_buf = alloc(new_size, alignment);
|
void * new_buf = alloc(new_size, alignment);
|
||||||
memcpy(new_buf, buf, std::min(old_size, new_size));
|
memcpy(new_buf, buf, std::min(old_size, new_size));
|
||||||
free(buf, old_size);
|
free(buf, old_size);
|
||||||
@ -142,10 +192,43 @@ protected:
|
|||||||
|
|
||||||
static constexpr bool clear_memory = clear_memory_;
|
static constexpr bool clear_memory = clear_memory_;
|
||||||
|
|
||||||
|
// Freshly mmapped pages are copy-on-write references to a global zero page.
|
||||||
|
// On the first write, a page fault occurs, and an actual writable page is
|
||||||
|
// allocated. If we are going to use this memory soon, such as when resizing
|
||||||
|
// hash tables, it makes sense to pre-fault the pages by passing
|
||||||
|
// MAP_POPULATE to mmap(). This takes some time, but should be faster
|
||||||
|
// overall than having a hot loop interrupted by page faults.
|
||||||
|
// It is only supported on Linux.
|
||||||
|
static constexpr int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS
|
||||||
|
#if defined(OS_LINUX)
|
||||||
|
| (mmap_populate ? MAP_POPULATE : 0)
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void * allocNoTrack(size_t size, size_t alignment)
|
void * allocNoTrack(size_t size, size_t alignment)
|
||||||
{
|
{
|
||||||
void * buf;
|
void * buf;
|
||||||
|
size_t mmap_min_alignment = ::getPageSize();
|
||||||
|
|
||||||
|
if (size >= MMAP_THRESHOLD)
|
||||||
|
{
|
||||||
|
if (alignment > mmap_min_alignment)
|
||||||
|
throw DB::Exception(DB::ErrorCodes::BAD_ARGUMENTS,
|
||||||
|
"Too large alignment {}: more than page size when allocating {}.",
|
||||||
|
ReadableSize(alignment), ReadableSize(size));
|
||||||
|
|
||||||
|
buf = mmap(getMmapHint(), size, PROT_READ | PROT_WRITE,
|
||||||
|
mmap_flags, -1, 0);
|
||||||
|
if (MAP_FAILED == buf)
|
||||||
|
DB::throwFromErrno(fmt::format("Allocator: Cannot mmap {}.", ReadableSize(size)), DB::ErrorCodes::CANNOT_ALLOCATE_MEMORY);
|
||||||
|
/// No need for zero-fill, because mmap guarantees it.
|
||||||
|
|
||||||
|
CurrentMetrics::add(CurrentMetrics::MMappedAllocs);
|
||||||
|
CurrentMetrics::add(CurrentMetrics::MMappedAllocBytes, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (alignment <= MALLOC_MIN_ALIGNMENT)
|
if (alignment <= MALLOC_MIN_ALIGNMENT)
|
||||||
{
|
{
|
||||||
if constexpr (clear_memory)
|
if constexpr (clear_memory)
|
||||||
@ -168,13 +251,25 @@ private:
|
|||||||
if constexpr (clear_memory)
|
if constexpr (clear_memory)
|
||||||
memset(buf, 0, size);
|
memset(buf, 0, size);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeNoTrack(void * buf)
|
void freeNoTrack(void * buf, size_t size)
|
||||||
|
{
|
||||||
|
if (size >= MMAP_THRESHOLD)
|
||||||
|
{
|
||||||
|
if (0 != munmap(buf, size))
|
||||||
|
DB::throwFromErrno(fmt::format("Allocator: Cannot munmap {}.", ReadableSize(size)), DB::ErrorCodes::CANNOT_MUNMAP);
|
||||||
|
|
||||||
|
CurrentMetrics::sub(CurrentMetrics::MMappedAllocs);
|
||||||
|
CurrentMetrics::sub(CurrentMetrics::MMappedAllocBytes, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
::free(buf);
|
::free(buf);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void checkSize(size_t size)
|
void checkSize(size_t size)
|
||||||
{
|
{
|
||||||
@ -182,6 +277,21 @@ private:
|
|||||||
if (size >= 0x8000000000000000ULL)
|
if (size >= 0x8000000000000000ULL)
|
||||||
throw DB::Exception(DB::ErrorCodes::LOGICAL_ERROR, "Too large size ({}) passed to allocator. It indicates an error.", size);
|
throw DB::Exception(DB::ErrorCodes::LOGICAL_ERROR, "Too large size ({}) passed to allocator. It indicates an error.", size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
/// In debug builds, request mmap() at random addresses (a kind of ASLR), to
|
||||||
|
/// reproduce more memory stomping bugs. Note that Linux doesn't do it by
|
||||||
|
/// default. This may lead to worse TLB performance.
|
||||||
|
void * getMmapHint()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<void *>(std::uniform_int_distribution<intptr_t>(0x100000000000UL, 0x700000000000UL)(thread_local_rng));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void * getMmapHint()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -257,5 +367,7 @@ constexpr size_t allocatorInitialBytes<AllocatorWithStackMemory<
|
|||||||
|
|
||||||
/// Prevent implicit template instantiation of Allocator
|
/// Prevent implicit template instantiation of Allocator
|
||||||
|
|
||||||
extern template class Allocator<false>;
|
extern template class Allocator<false, false>;
|
||||||
extern template class Allocator<true>;
|
extern template class Allocator<true, false>;
|
||||||
|
extern template class Allocator<false, true>;
|
||||||
|
extern template class Allocator<true, true>;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* This file provides forward declarations for Allocator.
|
* This file provides forward declarations for Allocator.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <bool clear_memory_>
|
template <bool clear_memory_, bool mmap_populate = false>
|
||||||
class Allocator;
|
class Allocator;
|
||||||
|
|
||||||
template <typename Base, size_t N = 64, size_t Alignment = 1>
|
template <typename Base, size_t N = 64, size_t Alignment = 1>
|
||||||
|
@ -26,6 +26,14 @@
|
|||||||
#include <IO/WriteBufferFromString.h>
|
#include <IO/WriteBufferFromString.h>
|
||||||
#include <IO/Operators.h>
|
#include <IO/Operators.h>
|
||||||
|
|
||||||
|
#if USE_SSL
|
||||||
|
#include <format>
|
||||||
|
#include <IO/BufferWithOwnMemory.h>
|
||||||
|
#include <Compression/ICompressionCodec.h>
|
||||||
|
#include <Compression/CompressionCodecEncrypted.h>
|
||||||
|
#include <boost/algorithm/hex.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PREPROCESSED_SUFFIX "-preprocessed"
|
#define PREPROCESSED_SUFFIX "-preprocessed"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
@ -39,6 +47,9 @@ namespace ErrorCodes
|
|||||||
{
|
{
|
||||||
extern const int FILE_DOESNT_EXIST;
|
extern const int FILE_DOESNT_EXIST;
|
||||||
extern const int CANNOT_LOAD_CONFIG;
|
extern const int CANNOT_LOAD_CONFIG;
|
||||||
|
#if USE_SSL
|
||||||
|
extern const int BAD_ARGUMENTS;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For cutting preprocessed path to this base
|
/// For cutting preprocessed path to this base
|
||||||
@ -177,6 +188,72 @@ static void mergeAttributes(Element & config_element, Element & with_element)
|
|||||||
with_element_attributes->release();
|
with_element_attributes->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_SSL
|
||||||
|
|
||||||
|
std::string ConfigProcessor::encryptValue(const std::string & codec_name, const std::string & value)
|
||||||
|
{
|
||||||
|
EncryptionMethod method = getEncryptionMethod(codec_name);
|
||||||
|
CompressionCodecEncrypted codec(method);
|
||||||
|
|
||||||
|
Memory<> memory;
|
||||||
|
memory.resize(codec.getCompressedReserveSize(static_cast<UInt32>(value.size())));
|
||||||
|
auto bytes_written = codec.compress(value.data(), static_cast<UInt32>(value.size()), memory.data());
|
||||||
|
auto encrypted_value = std::string(memory.data(), bytes_written);
|
||||||
|
std::string hex_value;
|
||||||
|
boost::algorithm::hex(encrypted_value.begin(), encrypted_value.end(), std::back_inserter(hex_value));
|
||||||
|
return hex_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ConfigProcessor::decryptValue(const std::string & codec_name, const std::string & value)
|
||||||
|
{
|
||||||
|
EncryptionMethod method = getEncryptionMethod(codec_name);
|
||||||
|
CompressionCodecEncrypted codec(method);
|
||||||
|
|
||||||
|
Memory<> memory;
|
||||||
|
std::string encrypted_value;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
boost::algorithm::unhex(value, std::back_inserter(encrypted_value));
|
||||||
|
}
|
||||||
|
catch (const std::exception &)
|
||||||
|
{
|
||||||
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Cannot read encrypted text, check for valid characters [0-9a-fA-F] and length");
|
||||||
|
}
|
||||||
|
|
||||||
|
memory.resize(codec.readDecompressedBlockSize(encrypted_value.data()));
|
||||||
|
codec.decompress(encrypted_value.data(), static_cast<UInt32>(encrypted_value.size()), memory.data());
|
||||||
|
std::string decrypted_value = std::string(memory.data(), memory.size());
|
||||||
|
return decrypted_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigProcessor::decryptRecursive(Poco::XML::Node * config_root)
|
||||||
|
{
|
||||||
|
for (Node * node = config_root->firstChild(); node; node = node->nextSibling())
|
||||||
|
{
|
||||||
|
if (node->nodeType() == Node::ELEMENT_NODE)
|
||||||
|
{
|
||||||
|
Element & element = dynamic_cast<Element &>(*node);
|
||||||
|
if (element.hasAttribute("encryption_codec"))
|
||||||
|
{
|
||||||
|
const NodeListPtr children = element.childNodes();
|
||||||
|
if (children->length() != 1)
|
||||||
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Encrypted node {} cannot contain nested elements", node->nodeName());
|
||||||
|
|
||||||
|
Node * text_node = node->firstChild();
|
||||||
|
if (text_node->nodeType() != Node::TEXT_NODE)
|
||||||
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Encrypted node {} should have text node", node->nodeName());
|
||||||
|
|
||||||
|
auto encryption_codec = element.getAttribute("encryption_codec");
|
||||||
|
text_node->setNodeValue(decryptValue(encryption_codec, text_node->getNodeValue()));
|
||||||
|
}
|
||||||
|
decryptRecursive(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void ConfigProcessor::mergeRecursive(XMLDocumentPtr config, Node * config_root, const Node * with_root)
|
void ConfigProcessor::mergeRecursive(XMLDocumentPtr config, Node * config_root, const Node * with_root)
|
||||||
{
|
{
|
||||||
const NodeListPtr with_nodes = with_root->childNodes();
|
const NodeListPtr with_nodes = with_root->childNodes();
|
||||||
@ -694,7 +771,19 @@ ConfigProcessor::LoadedConfig ConfigProcessor::loadConfigWithZooKeeperIncludes(
|
|||||||
return LoadedConfig{configuration, has_zk_includes, !processed_successfully, config_xml, path};
|
return LoadedConfig{configuration, has_zk_includes, !processed_successfully, config_xml, path};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigProcessor::savePreprocessedConfig(const LoadedConfig & loaded_config, std::string preprocessed_dir)
|
#if USE_SSL
|
||||||
|
|
||||||
|
void ConfigProcessor::decryptEncryptedElements(LoadedConfig & loaded_config)
|
||||||
|
{
|
||||||
|
CompressionCodecEncrypted::Configuration::instance().tryLoad(*loaded_config.configuration, "encryption_codecs");
|
||||||
|
Node * config_root = getRootNode(loaded_config.preprocessed_xml.get());
|
||||||
|
decryptRecursive(config_root);
|
||||||
|
loaded_config.configuration = new Poco::Util::XMLConfiguration(loaded_config.preprocessed_xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ConfigProcessor::savePreprocessedConfig(LoadedConfig & loaded_config, std::string preprocessed_dir)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -749,6 +838,12 @@ void ConfigProcessor::savePreprocessedConfig(const LoadedConfig & loaded_config,
|
|||||||
{
|
{
|
||||||
LOG_WARNING(log, "Couldn't save preprocessed config to {}: {}", preprocessed_path, e.displayText());
|
LOG_WARNING(log, "Couldn't save preprocessed config to {}: {}", preprocessed_path, e.displayText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_SSL
|
||||||
|
std::string preprocessed_file_name = fs::path(preprocessed_path).filename();
|
||||||
|
if (preprocessed_file_name == "config.xml" || preprocessed_file_name == std::format("config{}.xml", PREPROCESSED_SUFFIX))
|
||||||
|
decryptEncryptedElements(loaded_config);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigProcessor::setConfigPath(const std::string & config_path)
|
void ConfigProcessor::setConfigPath(const std::string & config_path)
|
||||||
|
@ -97,7 +97,7 @@ public:
|
|||||||
|
|
||||||
/// Save preprocessed config to specified directory.
|
/// Save preprocessed config to specified directory.
|
||||||
/// If preprocessed_dir is empty - calculate from loaded_config.path + /preprocessed_configs/
|
/// If preprocessed_dir is empty - calculate from loaded_config.path + /preprocessed_configs/
|
||||||
void savePreprocessedConfig(const LoadedConfig & loaded_config, std::string preprocessed_dir);
|
void savePreprocessedConfig(LoadedConfig & loaded_config, std::string preprocessed_dir);
|
||||||
|
|
||||||
/// Set path of main config.xml. It will be cut from all configs placed to preprocessed_configs/
|
/// Set path of main config.xml. It will be cut from all configs placed to preprocessed_configs/
|
||||||
static void setConfigPath(const std::string & config_path);
|
static void setConfigPath(const std::string & config_path);
|
||||||
@ -109,6 +109,14 @@ public:
|
|||||||
/// Is the file named as result of config preprocessing, not as original files.
|
/// Is the file named as result of config preprocessing, not as original files.
|
||||||
static bool isPreprocessedFile(const std::string & config_path);
|
static bool isPreprocessedFile(const std::string & config_path);
|
||||||
|
|
||||||
|
#if USE_SSL
|
||||||
|
/// Encrypt text value
|
||||||
|
static std::string encryptValue(const std::string & codec_name, const std::string & value);
|
||||||
|
|
||||||
|
/// Decrypt value
|
||||||
|
static std::string decryptValue(const std::string & codec_name, const std::string & value);
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline const auto SUBSTITUTION_ATTRS = {"incl", "from_zk", "from_env"};
|
static inline const auto SUBSTITUTION_ATTRS = {"incl", "from_zk", "from_env"};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -127,6 +135,13 @@ private:
|
|||||||
|
|
||||||
using NodePtr = Poco::AutoPtr<Poco::XML::Node>;
|
using NodePtr = Poco::AutoPtr<Poco::XML::Node>;
|
||||||
|
|
||||||
|
#if USE_SSL
|
||||||
|
void decryptRecursive(Poco::XML::Node * config_root);
|
||||||
|
|
||||||
|
/// Decrypt elements in config with specified encryption attributes
|
||||||
|
void decryptEncryptedElements(LoadedConfig & loaded_config);
|
||||||
|
#endif
|
||||||
|
|
||||||
void mergeRecursive(XMLDocumentPtr config, Poco::XML::Node * config_root, const Poco::XML::Node * with_root);
|
void mergeRecursive(XMLDocumentPtr config, Poco::XML::Node * config_root, const Poco::XML::Node * with_root);
|
||||||
|
|
||||||
void merge(XMLDocumentPtr config, XMLDocumentPtr with);
|
void merge(XMLDocumentPtr config, XMLDocumentPtr with);
|
||||||
|
@ -109,12 +109,26 @@ namespace
|
|||||||
parent_xml_node.setAttribute(attribute_name, value);
|
parent_xml_node.setAttribute(attribute_name, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (key == "#text" && value_node.IsScalar())
|
||||||
|
{
|
||||||
|
for (Node * child_node = parent_xml_node.firstChild(); child_node; child_node = child_node->nextSibling())
|
||||||
|
if (child_node->nodeType() == Node::TEXT_NODE)
|
||||||
|
throw Exception(ErrorCodes::CANNOT_PARSE_YAML,
|
||||||
|
"YAMLParser has encountered node with several text nodes "
|
||||||
|
"and cannot continue parsing of the file");
|
||||||
|
std::string value = value_node.as<std::string>();
|
||||||
|
Poco::AutoPtr<Poco::XML::Text> xml_value = xml_document->createTextNode(value);
|
||||||
|
parent_xml_node.appendChild(xml_value);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Poco::AutoPtr<Poco::XML::Element> xml_key = xml_document->createElement(key);
|
Poco::AutoPtr<Poco::XML::Element> xml_key = xml_document->createElement(key);
|
||||||
parent_xml_node.appendChild(xml_key);
|
parent_xml_node.appendChild(xml_key);
|
||||||
processNode(value_node, *xml_key);
|
processNode(value_node, *xml_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,8 +149,10 @@
|
|||||||
M(RestartReplicaThreadsActive, "Number of threads in the RESTART REPLICA thread pool running a task.") \
|
M(RestartReplicaThreadsActive, "Number of threads in the RESTART REPLICA thread pool running a task.") \
|
||||||
M(QueryPipelineExecutorThreads, "Number of threads in the PipelineExecutor thread pool.") \
|
M(QueryPipelineExecutorThreads, "Number of threads in the PipelineExecutor thread pool.") \
|
||||||
M(QueryPipelineExecutorThreadsActive, "Number of threads in the PipelineExecutor thread pool running a task.") \
|
M(QueryPipelineExecutorThreadsActive, "Number of threads in the PipelineExecutor thread pool running a task.") \
|
||||||
M(ParquetDecoderThreads, "Number of threads in the ParquetBlockInputFormat thread pool running a task.") \
|
M(ParquetDecoderThreads, "Number of threads in the ParquetBlockInputFormat thread pool.") \
|
||||||
M(ParquetDecoderThreadsActive, "Number of threads in the ParquetBlockInputFormat thread pool.") \
|
M(ParquetDecoderThreadsActive, "Number of threads in the ParquetBlockInputFormat thread pool running a task.") \
|
||||||
|
M(ParquetEncoderThreads, "Number of threads in ParquetBlockOutputFormat thread pool.") \
|
||||||
|
M(ParquetEncoderThreadsActive, "Number of threads in ParquetBlockOutputFormat thread pool running a task.") \
|
||||||
M(OutdatedPartsLoadingThreads, "Number of threads in the threadpool for loading Outdated data parts.") \
|
M(OutdatedPartsLoadingThreads, "Number of threads in the threadpool for loading Outdated data parts.") \
|
||||||
M(OutdatedPartsLoadingThreadsActive, "Number of active threads in the threadpool for loading Outdated data parts.") \
|
M(OutdatedPartsLoadingThreadsActive, "Number of active threads in the threadpool for loading Outdated data parts.") \
|
||||||
M(DistributedBytesToInsert, "Number of pending bytes to process for asynchronous insertion into Distributed tables. Number of bytes for every shard is summed.") \
|
M(DistributedBytesToInsert, "Number of pending bytes to process for asynchronous insertion into Distributed tables. Number of bytes for every shard is summed.") \
|
||||||
@ -173,6 +175,8 @@
|
|||||||
M(PartsInMemory, "In-memory parts.") \
|
M(PartsInMemory, "In-memory parts.") \
|
||||||
M(MMappedFiles, "Total number of mmapped files.") \
|
M(MMappedFiles, "Total number of mmapped files.") \
|
||||||
M(MMappedFileBytes, "Sum size of mmapped file regions.") \
|
M(MMappedFileBytes, "Sum size of mmapped file regions.") \
|
||||||
|
M(MMappedAllocs, "Total number of mmapped allocations") \
|
||||||
|
M(MMappedAllocBytes, "Sum bytes of mmapped allocations") \
|
||||||
M(AsynchronousReadWait, "Number of threads waiting for asynchronous read.") \
|
M(AsynchronousReadWait, "Number of threads waiting for asynchronous read.") \
|
||||||
M(PendingAsyncInsert, "Number of asynchronous inserts that are waiting for flush.") \
|
M(PendingAsyncInsert, "Number of asynchronous inserts that are waiting for flush.") \
|
||||||
M(KafkaConsumers, "Number of active Kafka consumers") \
|
M(KafkaConsumers, "Number of active Kafka consumers") \
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* table, so it makes sense to pre-fault the pages so that page faults don't
|
* table, so it makes sense to pre-fault the pages so that page faults don't
|
||||||
* interrupt the resize loop. Set the allocator parameter accordingly.
|
* interrupt the resize loop. Set the allocator parameter accordingly.
|
||||||
*/
|
*/
|
||||||
using HashTableAllocator = Allocator<true /* clear_memory */>;
|
using HashTableAllocator = Allocator<true /* clear_memory */, true /* mmap_populate */>;
|
||||||
|
|
||||||
template <size_t initial_bytes = 64>
|
template <size_t initial_bytes = 64>
|
||||||
using HashTableAllocatorWithStackMemory = AllocatorWithStackMemory<HashTableAllocator, initial_bytes>;
|
using HashTableAllocatorWithStackMemory = AllocatorWithStackMemory<HashTableAllocator, initial_bytes>;
|
||||||
|
@ -113,13 +113,19 @@ public:
|
|||||||
if ((reinterpret_cast<uintptr_t>(p) & 2048) == 0)
|
if ((reinterpret_cast<uintptr_t>(p) & 2048) == 0)
|
||||||
{
|
{
|
||||||
memcpy(&n[0], p, 8);
|
memcpy(&n[0], p, 8);
|
||||||
|
if constexpr (std::endian::native == std::endian::little)
|
||||||
n[0] &= -1ULL >> s;
|
n[0] &= -1ULL >> s;
|
||||||
|
else
|
||||||
|
n[0] &= -1ULL << s;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char * lp = x.data + x.size - 8;
|
const char * lp = x.data + x.size - 8;
|
||||||
memcpy(&n[0], lp, 8);
|
memcpy(&n[0], lp, 8);
|
||||||
|
if constexpr (std::endian::native == std::endian::little)
|
||||||
n[0] >>= s;
|
n[0] >>= s;
|
||||||
|
else
|
||||||
|
n[0] <<= s;
|
||||||
}
|
}
|
||||||
auto res = hash(k8);
|
auto res = hash(k8);
|
||||||
auto buck = getBucketFromHash(res);
|
auto buck = getBucketFromHash(res);
|
||||||
@ -131,7 +137,10 @@ public:
|
|||||||
memcpy(&n[0], p, 8);
|
memcpy(&n[0], p, 8);
|
||||||
const char * lp = x.data + x.size - 8;
|
const char * lp = x.data + x.size - 8;
|
||||||
memcpy(&n[1], lp, 8);
|
memcpy(&n[1], lp, 8);
|
||||||
|
if constexpr (std::endian::native == std::endian::little)
|
||||||
n[1] >>= s;
|
n[1] >>= s;
|
||||||
|
else
|
||||||
|
n[1] <<= s;
|
||||||
auto res = hash(k16);
|
auto res = hash(k16);
|
||||||
auto buck = getBucketFromHash(res);
|
auto buck = getBucketFromHash(res);
|
||||||
keyHolderDiscardKey(key_holder);
|
keyHolderDiscardKey(key_holder);
|
||||||
@ -142,7 +151,10 @@ public:
|
|||||||
memcpy(&n[0], p, 16);
|
memcpy(&n[0], p, 16);
|
||||||
const char * lp = x.data + x.size - 8;
|
const char * lp = x.data + x.size - 8;
|
||||||
memcpy(&n[2], lp, 8);
|
memcpy(&n[2], lp, 8);
|
||||||
|
if constexpr (std::endian::native == std::endian::little)
|
||||||
n[2] >>= s;
|
n[2] >>= s;
|
||||||
|
else
|
||||||
|
n[2] <<= s;
|
||||||
auto res = hash(k24);
|
auto res = hash(k24);
|
||||||
auto buck = getBucketFromHash(res);
|
auto buck = getBucketFromHash(res);
|
||||||
keyHolderDiscardKey(key_holder);
|
keyHolderDiscardKey(key_holder);
|
||||||
|
@ -27,15 +27,9 @@ struct Interval
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename IntervalStorageType>
|
template <typename IntervalStorageType>
|
||||||
bool operator<(const Interval<IntervalStorageType> & lhs, const Interval<IntervalStorageType> & rhs)
|
auto operator<=>(const Interval<IntervalStorageType> & lhs, const Interval<IntervalStorageType> & rhs)
|
||||||
{
|
{
|
||||||
return std::tie(lhs.left, lhs.right) < std::tie(rhs.left, rhs.right);
|
return std::tie(lhs.left, lhs.right) <=> std::tie(rhs.left, rhs.right);
|
||||||
}
|
|
||||||
|
|
||||||
template <typename IntervalStorageType>
|
|
||||||
bool operator<=(const Interval<IntervalStorageType> & lhs, const Interval<IntervalStorageType> & rhs)
|
|
||||||
{
|
|
||||||
return std::tie(lhs.left, lhs.right) <= std::tie(rhs.left, rhs.right);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename IntervalStorageType>
|
template <typename IntervalStorageType>
|
||||||
@ -44,24 +38,6 @@ bool operator==(const Interval<IntervalStorageType> & lhs, const Interval<Interv
|
|||||||
return std::tie(lhs.left, lhs.right) == std::tie(rhs.left, rhs.right);
|
return std::tie(lhs.left, lhs.right) == std::tie(rhs.left, rhs.right);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename IntervalStorageType>
|
|
||||||
bool operator!=(const Interval<IntervalStorageType> & lhs, const Interval<IntervalStorageType> & rhs)
|
|
||||||
{
|
|
||||||
return std::tie(lhs.left, lhs.right) != std::tie(rhs.left, rhs.right);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename IntervalStorageType>
|
|
||||||
bool operator>(const Interval<IntervalStorageType> & lhs, const Interval<IntervalStorageType> & rhs)
|
|
||||||
{
|
|
||||||
return std::tie(lhs.left, lhs.right) > std::tie(rhs.left, rhs.right);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename IntervalStorageType>
|
|
||||||
bool operator>=(const Interval<IntervalStorageType> & lhs, const Interval<IntervalStorageType> & rhs)
|
|
||||||
{
|
|
||||||
return std::tie(lhs.left, lhs.right) >= std::tie(rhs.left, rhs.right);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct IntervalTreeVoidValue
|
struct IntervalTreeVoidValue
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
@ -43,6 +43,17 @@ struct PreformattedMessage
|
|||||||
operator const std::string & () const { return text; }
|
operator const std::string & () const { return text; }
|
||||||
operator std::string () && { return std::move(text); }
|
operator std::string () && { return std::move(text); }
|
||||||
operator fmt::format_string<> () const { UNREACHABLE(); }
|
operator fmt::format_string<> () const { UNREACHABLE(); }
|
||||||
|
|
||||||
|
void apply(std::string & out_text, std::string_view & out_format_string) const &
|
||||||
|
{
|
||||||
|
out_text = text;
|
||||||
|
out_format_string = format_string;
|
||||||
|
}
|
||||||
|
void apply(std::string & out_text, std::string_view & out_format_string) &&
|
||||||
|
{
|
||||||
|
out_text = std::move(text);
|
||||||
|
out_format_string = format_string;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
@ -99,10 +110,33 @@ template <typename T> constexpr std::string_view tryGetStaticFormatString(T && x
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constexpr ifs are not like ifdefs, and compiler still checks that unneeded code can be compiled
|
||||||
|
/// This template is useful to avoid compilation failures when condition of some "constexpr if" is false
|
||||||
|
template<bool enable> struct ConstexprIfsAreNotIfdefs
|
||||||
|
{
|
||||||
|
template <typename T> constexpr static std::string_view getStaticFormatString(T &&) { return {}; }
|
||||||
|
template <typename T> static PreformattedMessage getPreformatted(T &&) { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct ConstexprIfsAreNotIfdefs<true>
|
||||||
|
{
|
||||||
|
template <typename T> consteval static std::string_view getStaticFormatString(T && x)
|
||||||
|
{
|
||||||
|
/// See tryGetStaticFormatString(...)
|
||||||
|
static_assert(!std::is_same_v<std::string, std::decay_t<T>>);
|
||||||
|
static_assert(std::is_nothrow_convertible<T, const char * const>::value);
|
||||||
|
static_assert(!std::is_pointer<T>::value);
|
||||||
|
return std::string_view(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> static T && getPreformatted(T && x) { return std::forward<T>(x); }
|
||||||
|
};
|
||||||
|
|
||||||
template <typename... Ts> constexpr size_t numArgs(Ts &&...) { return sizeof...(Ts); }
|
template <typename... Ts> constexpr size_t numArgs(Ts &&...) { return sizeof...(Ts); }
|
||||||
template <typename T, typename... Ts> constexpr auto firstArg(T && x, Ts &&...) { return std::forward<T>(x); }
|
template <typename T, typename... Ts> constexpr auto firstArg(T && x, Ts &&...) { return std::forward<T>(x); }
|
||||||
/// For implicit conversion of fmt::basic_runtime<> to char* for std::string ctor
|
/// For implicit conversion of fmt::basic_runtime<> to char* for std::string ctor
|
||||||
template <typename T, typename... Ts> constexpr auto firstArg(fmt::basic_runtime<T> && data, Ts &&...) { return data.str.data(); }
|
template <typename T, typename... Ts> constexpr auto firstArg(fmt::basic_runtime<T> && data, Ts &&...) { return data.str.data(); }
|
||||||
|
template <typename T, typename... Ts> constexpr auto firstArg(const fmt::basic_runtime<T> & data, Ts &&...) { return data.str.data(); }
|
||||||
|
|
||||||
consteval ssize_t formatStringCountArgsNum(const char * const str, size_t len)
|
consteval ssize_t formatStringCountArgsNum(const char * const str, size_t len)
|
||||||
{
|
{
|
||||||
@ -142,26 +176,19 @@ consteval void formatStringCheckArgsNumImpl(std::string_view str, size_t nargs)
|
|||||||
functionThatFailsCompilationOfConstevalFunctions("unexpected number of arguments in a format string");
|
functionThatFailsCompilationOfConstevalFunctions("unexpected number of arguments in a format string");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
|
||||||
struct CheckArgsNumHelperImpl
|
|
||||||
{
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
consteval CheckArgsNumHelperImpl(T && str)
|
consteval void formatStringCheckArgsNum(T && str, size_t nargs)
|
||||||
{
|
{
|
||||||
formatStringCheckArgsNumImpl(tryGetStaticFormatString(str), sizeof...(Args));
|
formatStringCheckArgsNumImpl(tryGetStaticFormatString(str), nargs);
|
||||||
}
|
}
|
||||||
|
template<typename T> inline void formatStringCheckArgsNum(fmt::basic_runtime<T> &&, size_t) {}
|
||||||
|
template<> inline void formatStringCheckArgsNum(PreformattedMessage &, size_t) {}
|
||||||
|
template<> inline void formatStringCheckArgsNum(const PreformattedMessage &, size_t) {}
|
||||||
|
template<> inline void formatStringCheckArgsNum(PreformattedMessage &&, size_t) {}
|
||||||
|
|
||||||
/// No checks for fmt::runtime and PreformattedMessage
|
template<typename T> struct FormatStringTypeInfo{ static constexpr bool is_static = true; static constexpr bool has_format = true; };
|
||||||
template<typename T> CheckArgsNumHelperImpl(fmt::basic_runtime<T> &&) {}
|
template<typename T> struct FormatStringTypeInfo<fmt::basic_runtime<T>> { static constexpr bool is_static = false; static constexpr bool has_format = false; };
|
||||||
template<> CheckArgsNumHelperImpl(PreformattedMessage &) {}
|
template<> struct FormatStringTypeInfo<PreformattedMessage> { static constexpr bool is_static = false; static constexpr bool has_format = true; };
|
||||||
template<> CheckArgsNumHelperImpl(const PreformattedMessage &) {}
|
|
||||||
template<> CheckArgsNumHelperImpl(PreformattedMessage &&) {}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename... Args> using CheckArgsNumHelper = CheckArgsNumHelperImpl<std::type_identity_t<Args>...>;
|
|
||||||
template <typename... Args> void formatStringCheckArgsNum(CheckArgsNumHelper<Args...>, Args &&...) {}
|
|
||||||
|
|
||||||
|
|
||||||
/// This wrapper helps to avoid too frequent and noisy log messages.
|
/// This wrapper helps to avoid too frequent and noisy log messages.
|
||||||
/// For each pair (logger_name, format_string) it remembers when such a message was logged the last time.
|
/// For each pair (logger_name, format_string) it remembers when such a message was logged the last time.
|
||||||
|
@ -95,6 +95,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
static constexpr auto USAGE_EVENT_NAME = "MemoryTrackerUsage";
|
static constexpr auto USAGE_EVENT_NAME = "MemoryTrackerUsage";
|
||||||
|
static constexpr auto PEAK_USAGE_EVENT_NAME = "MemoryTrackerPeakUsage";
|
||||||
|
|
||||||
explicit MemoryTracker(VariableContext level_ = VariableContext::Thread);
|
explicit MemoryTracker(VariableContext level_ = VariableContext::Thread);
|
||||||
explicit MemoryTracker(MemoryTracker * parent_, VariableContext level_ = VariableContext::Thread);
|
explicit MemoryTracker(MemoryTracker * parent_, VariableContext level_ = VariableContext::Thread);
|
||||||
|
@ -15,4 +15,14 @@ template class PODArray<Int8, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADD
|
|||||||
template class PODArray<Int16, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;
|
template class PODArray<Int16, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;
|
||||||
template class PODArray<Int32, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;
|
template class PODArray<Int32, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;
|
||||||
template class PODArray<Int64, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;
|
template class PODArray<Int64, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;
|
||||||
|
|
||||||
|
template class PODArray<UInt8, 4096, Allocator<false>, 0, 0>;
|
||||||
|
template class PODArray<UInt16, 4096, Allocator<false>, 0, 0>;
|
||||||
|
template class PODArray<UInt32, 4096, Allocator<false>, 0, 0>;
|
||||||
|
template class PODArray<UInt64, 4096, Allocator<false>, 0, 0>;
|
||||||
|
|
||||||
|
template class PODArray<Int8, 4096, Allocator<false>, 0, 0>;
|
||||||
|
template class PODArray<Int16, 4096, Allocator<false>, 0, 0>;
|
||||||
|
template class PODArray<Int32, 4096, Allocator<false>, 0, 0>;
|
||||||
|
template class PODArray<Int64, 4096, Allocator<false>, 0, 0>;
|
||||||
}
|
}
|
||||||
|
@ -783,4 +783,15 @@ extern template class PODArray<Int8, 4096, Allocator<false>, PADDING_FOR_SIMD -
|
|||||||
extern template class PODArray<Int16, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;
|
extern template class PODArray<Int16, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;
|
||||||
extern template class PODArray<Int32, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;
|
extern template class PODArray<Int32, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;
|
||||||
extern template class PODArray<Int64, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;
|
extern template class PODArray<Int64, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;
|
||||||
|
|
||||||
|
extern template class PODArray<UInt8, 4096, Allocator<false>, 0, 0>;
|
||||||
|
extern template class PODArray<UInt16, 4096, Allocator<false>, 0, 0>;
|
||||||
|
extern template class PODArray<UInt32, 4096, Allocator<false>, 0, 0>;
|
||||||
|
extern template class PODArray<UInt64, 4096, Allocator<false>, 0, 0>;
|
||||||
|
|
||||||
|
extern template class PODArray<Int8, 4096, Allocator<false>, 0, 0>;
|
||||||
|
extern template class PODArray<Int16, 4096, Allocator<false>, 0, 0>;
|
||||||
|
extern template class PODArray<Int32, 4096, Allocator<false>, 0, 0>;
|
||||||
|
extern template class PODArray<Int64, 4096, Allocator<false>, 0, 0>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -58,8 +58,8 @@
|
|||||||
M(TableFunctionExecute, "Number of table function calls.") \
|
M(TableFunctionExecute, "Number of table function calls.") \
|
||||||
M(MarkCacheHits, "Number of times an entry has been found in the mark cache, so we didn't have to load a mark file.") \
|
M(MarkCacheHits, "Number of times an entry has been found in the mark cache, so we didn't have to load a mark file.") \
|
||||||
M(MarkCacheMisses, "Number of times an entry has not been found in the mark cache, so we had to load a mark file in memory, which is a costly operation, adding to query latency.") \
|
M(MarkCacheMisses, "Number of times an entry has not been found in the mark cache, so we had to load a mark file in memory, which is a costly operation, adding to query latency.") \
|
||||||
M(QueryCacheHits, "Number of times a query result has been found in the query cache (and query computation was avoided).") \
|
M(QueryCacheHits, "Number of times a query result has been found in the query cache (and query computation was avoided). Only updated for SELECT queries with SETTING use_query_cache = 1.") \
|
||||||
M(QueryCacheMisses, "Number of times a query result has not been found in the query cache (and required query computation).") \
|
M(QueryCacheMisses, "Number of times a query result has not been found in the query cache (and required query computation). Only updated for SELECT queries with SETTING use_query_cache = 1.") \
|
||||||
M(CreatedReadBufferOrdinary, "Number of times ordinary read buffer was created for reading data (while choosing among other read methods).") \
|
M(CreatedReadBufferOrdinary, "Number of times ordinary read buffer was created for reading data (while choosing among other read methods).") \
|
||||||
M(CreatedReadBufferDirectIO, "Number of times a read buffer with O_DIRECT was created for reading data (while choosing among other read methods).") \
|
M(CreatedReadBufferDirectIO, "Number of times a read buffer with O_DIRECT was created for reading data (while choosing among other read methods).") \
|
||||||
M(CreatedReadBufferDirectIOFailed, "Number of times a read buffer with O_DIRECT was attempted to be created for reading data (while choosing among other read methods), but the OS did not allow it (due to lack of filesystem support or other reasons) and we fallen back to the ordinary reading method.") \
|
M(CreatedReadBufferDirectIOFailed, "Number of times a read buffer with O_DIRECT was attempted to be created for reading data (while choosing among other read methods), but the OS did not allow it (due to lack of filesystem support or other reasons) and we fallen back to the ordinary reading method.") \
|
||||||
|
@ -83,7 +83,7 @@ ProgressIndication::MemoryUsage ProgressIndication::getMemoryUsage() const
|
|||||||
[](MemoryUsage const & acc, auto const & host_data)
|
[](MemoryUsage const & acc, auto const & host_data)
|
||||||
{
|
{
|
||||||
UInt64 host_usage = host_data.second.memory_usage;
|
UInt64 host_usage = host_data.second.memory_usage;
|
||||||
return MemoryUsage{.total = acc.total + host_usage, .max = std::max(acc.max, host_usage)};
|
return MemoryUsage{.total = acc.total + host_usage, .max = std::max(acc.max, host_usage), .peak = std::max(acc.peak, host_data.second.peak_memory_usage)};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ void ProgressIndication::writeProgress(WriteBufferFromFileDescriptor & message)
|
|||||||
std::string profiling_msg;
|
std::string profiling_msg;
|
||||||
|
|
||||||
double cpu_usage = getCPUUsage();
|
double cpu_usage = getCPUUsage();
|
||||||
auto [memory_usage, max_host_usage] = getMemoryUsage();
|
auto [memory_usage, max_host_usage, peak_usage] = getMemoryUsage();
|
||||||
|
|
||||||
if (cpu_usage > 0 || memory_usage > 0)
|
if (cpu_usage > 0 || memory_usage > 0)
|
||||||
{
|
{
|
||||||
|
@ -22,6 +22,9 @@ struct ThreadEventData
|
|||||||
UInt64 user_ms = 0;
|
UInt64 user_ms = 0;
|
||||||
UInt64 system_ms = 0;
|
UInt64 system_ms = 0;
|
||||||
UInt64 memory_usage = 0;
|
UInt64 memory_usage = 0;
|
||||||
|
|
||||||
|
// -1 used as flag 'is not show for old servers'
|
||||||
|
Int64 peak_memory_usage = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
using HostToTimesMap = std::unordered_map<String, ThreadEventData>;
|
using HostToTimesMap = std::unordered_map<String, ThreadEventData>;
|
||||||
@ -64,6 +67,7 @@ private:
|
|||||||
{
|
{
|
||||||
UInt64 total = 0;
|
UInt64 total = 0;
|
||||||
UInt64 max = 0;
|
UInt64 max = 0;
|
||||||
|
Int64 peak = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
MemoryUsage getMemoryUsage() const;
|
MemoryUsage getMemoryUsage() const;
|
||||||
|
@ -185,7 +185,7 @@ void SystemLogQueue<LogElement>::confirm(uint64_t to_flush_end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename LogElement>
|
template <typename LogElement>
|
||||||
SystemLogQueue<LogElement>::Index SystemLogQueue<LogElement>::pop(std::vector<LogElement>& output, bool& should_prepare_tables_anyway, bool& exit_this_thread)
|
typename SystemLogQueue<LogElement>::Index SystemLogQueue<LogElement>::pop(std::vector<LogElement>& output, bool& should_prepare_tables_anyway, bool& exit_this_thread)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(mutex);
|
std::unique_lock lock(mutex);
|
||||||
flush_event.wait_for(lock,
|
flush_event.wait_for(lock,
|
||||||
|
@ -82,3 +82,8 @@ endif()
|
|||||||
|
|
||||||
clickhouse_add_executable (interval_tree interval_tree.cpp)
|
clickhouse_add_executable (interval_tree interval_tree.cpp)
|
||||||
target_link_libraries (interval_tree PRIVATE dbms)
|
target_link_libraries (interval_tree PRIVATE dbms)
|
||||||
|
|
||||||
|
if (ENABLE_SSL)
|
||||||
|
clickhouse_add_executable (encrypt_decrypt encrypt_decrypt.cpp)
|
||||||
|
target_link_libraries (encrypt_decrypt PRIVATE dbms)
|
||||||
|
endif()
|
||||||
|
61
src/Common/examples/encrypt_decrypt.cpp
Normal file
61
src/Common/examples/encrypt_decrypt.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#include <Common/Config/ConfigProcessor.h>
|
||||||
|
#include <Compression/ICompressionCodec.h>
|
||||||
|
#include <Compression/CompressionCodecEncrypted.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
/** This test program encrypts or decrypts text values using a symmetric encryption codec like AES_128_GCM_SIV or AES_256_GCM_SIV.
|
||||||
|
* Keys for codecs are loaded from <encryption_codecs> section of configuration file.
|
||||||
|
*
|
||||||
|
* How to use:
|
||||||
|
* ./encrypt_decrypt /etc/clickhouse-server/config.xml -e AES_128_GCM_SIV text_to_encrypt
|
||||||
|
*/
|
||||||
|
|
||||||
|
int main(int argc, char ** argv)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (argc != 5)
|
||||||
|
{
|
||||||
|
std::cerr << "Usage:" << std::endl
|
||||||
|
<< " " << argv[0] << " path action codec value" << std::endl
|
||||||
|
<< "path: path to configuration file." << std::endl
|
||||||
|
<< "action: -e for encryption and -d for decryption." << std::endl
|
||||||
|
<< "codec: AES_128_GCM_SIV or AES_256_GCM_SIV." << std::endl << std::endl
|
||||||
|
<< "Example:" << std::endl
|
||||||
|
<< " ./encrypt_decrypt /etc/clickhouse-server/config.xml -e AES_128_GCM_SIV text_to_encrypt";
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string action = argv[2];
|
||||||
|
std::string codec_name = argv[3];
|
||||||
|
std::string value = argv[4];
|
||||||
|
|
||||||
|
DB::ConfigProcessor processor(argv[1], false, true);
|
||||||
|
auto loaded_config = processor.loadConfig();
|
||||||
|
DB::CompressionCodecEncrypted::Configuration::instance().tryLoad(*loaded_config.configuration, "encryption_codecs");
|
||||||
|
|
||||||
|
if (action == "-e")
|
||||||
|
std::cout << processor.encryptValue(codec_name, value) << std::endl;
|
||||||
|
else if (action == "-d")
|
||||||
|
std::cout << processor.decryptValue(codec_name, value) << std::endl;
|
||||||
|
else
|
||||||
|
std::cerr << "Unknown action: " << action << std::endl;
|
||||||
|
}
|
||||||
|
catch (Poco::Exception & e)
|
||||||
|
{
|
||||||
|
std::cerr << "Exception: " << e.displayText() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
catch (std::exception & e)
|
||||||
|
{
|
||||||
|
std::cerr << "std::exception: " << e.what() << std::endl;
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cerr << "Some exception" << std::endl;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/// Macros for convenient usage of Poco logger.
|
/// Macros for convenient usage of Poco logger.
|
||||||
|
#include <unistd.h>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <Poco/Logger.h>
|
#include <Poco/Logger.h>
|
||||||
#include <Poco/Message.h>
|
#include <Poco/Message.h>
|
||||||
@ -28,6 +28,32 @@ namespace
|
|||||||
|
|
||||||
#define LOG_IMPL_FIRST_ARG(X, ...) X
|
#define LOG_IMPL_FIRST_ARG(X, ...) X
|
||||||
|
|
||||||
|
/// Copy-paste from contrib/libpq/include/c.h
|
||||||
|
/// There's no easy way to count the number of arguments without evaluating these arguments...
|
||||||
|
#define CH_VA_ARGS_NARGS(...) \
|
||||||
|
CH_VA_ARGS_NARGS_(__VA_ARGS__, \
|
||||||
|
63,62,61,60, \
|
||||||
|
59,58,57,56,55,54,53,52,51,50, \
|
||||||
|
49,48,47,46,45,44,43,42,41,40, \
|
||||||
|
39,38,37,36,35,34,33,32,31,30, \
|
||||||
|
29,28,27,26,25,24,23,22,21,20, \
|
||||||
|
19,18,17,16,15,14,13,12,11,10, \
|
||||||
|
9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||||
|
#define CH_VA_ARGS_NARGS_( \
|
||||||
|
_01,_02,_03,_04,_05,_06,_07,_08,_09,_10, \
|
||||||
|
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
|
||||||
|
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
|
||||||
|
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
|
||||||
|
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
|
||||||
|
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
|
||||||
|
_61,_62,_63, N, ...) \
|
||||||
|
(N)
|
||||||
|
|
||||||
|
#define LINE_NUM_AS_STRING_IMPL2(x) #x
|
||||||
|
#define LINE_NUM_AS_STRING_IMPL(x) LINE_NUM_AS_STRING_IMPL2(x)
|
||||||
|
#define LINE_NUM_AS_STRING LINE_NUM_AS_STRING_IMPL(__LINE__)
|
||||||
|
#define MESSAGE_FOR_EXCEPTION_ON_LOGGING "Failed to write a log message: " __FILE__ ":" LINE_NUM_AS_STRING "\n"
|
||||||
|
|
||||||
/// Logs a message to a specified logger with that level.
|
/// Logs a message to a specified logger with that level.
|
||||||
/// If more than one argument is provided,
|
/// If more than one argument is provided,
|
||||||
/// the first argument is interpreted as a template with {}-substitutions
|
/// the first argument is interpreted as a template with {}-substitutions
|
||||||
@ -39,21 +65,48 @@ namespace
|
|||||||
auto _logger = ::getLogger(logger); \
|
auto _logger = ::getLogger(logger); \
|
||||||
const bool _is_clients_log = (DB::CurrentThread::getGroup() != nullptr) && \
|
const bool _is_clients_log = (DB::CurrentThread::getGroup() != nullptr) && \
|
||||||
(DB::CurrentThread::get().getClientLogsLevel() >= (priority)); \
|
(DB::CurrentThread::get().getClientLogsLevel() >= (priority)); \
|
||||||
if (_is_clients_log || _logger->is((PRIORITY))) \
|
if (!_is_clients_log && !_logger->is((PRIORITY))) \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
try \
|
||||||
{ \
|
{ \
|
||||||
std::string formatted_message = numArgs(__VA_ARGS__) > 1 ? fmt::format(__VA_ARGS__) : firstArg(__VA_ARGS__); \
|
|
||||||
formatStringCheckArgsNum(__VA_ARGS__); \
|
|
||||||
if (auto _channel = _logger->getChannel()) \
|
|
||||||
{ \
|
|
||||||
std::string file_function; \
|
|
||||||
file_function += __FILE__; \
|
|
||||||
file_function += "; "; \
|
|
||||||
file_function += __PRETTY_FUNCTION__; \
|
|
||||||
Poco::Message poco_message(_logger->name(), formatted_message, \
|
|
||||||
(PRIORITY), file_function.c_str(), __LINE__, tryGetStaticFormatString(LOG_IMPL_FIRST_ARG(__VA_ARGS__))); \
|
|
||||||
_channel->log(poco_message); \
|
|
||||||
} \
|
|
||||||
ProfileEvents::incrementForLogMessage(PRIORITY); \
|
ProfileEvents::incrementForLogMessage(PRIORITY); \
|
||||||
|
auto _channel = _logger->getChannel(); \
|
||||||
|
if (!_channel) \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
constexpr size_t _nargs = CH_VA_ARGS_NARGS(__VA_ARGS__); \
|
||||||
|
using LogTypeInfo = FormatStringTypeInfo<std::decay_t<decltype(LOG_IMPL_FIRST_ARG(__VA_ARGS__))>>; \
|
||||||
|
\
|
||||||
|
std::string_view _format_string; \
|
||||||
|
std::string _formatted_message; \
|
||||||
|
\
|
||||||
|
if constexpr (LogTypeInfo::is_static) \
|
||||||
|
{ \
|
||||||
|
formatStringCheckArgsNum(LOG_IMPL_FIRST_ARG(__VA_ARGS__), _nargs - 1); \
|
||||||
|
_format_string = ConstexprIfsAreNotIfdefs<LogTypeInfo::is_static>::getStaticFormatString(LOG_IMPL_FIRST_ARG(__VA_ARGS__)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
constexpr bool is_preformatted_message = !LogTypeInfo::is_static && LogTypeInfo::has_format; \
|
||||||
|
if constexpr (is_preformatted_message) \
|
||||||
|
{ \
|
||||||
|
static_assert(_nargs == 1 || !is_preformatted_message); \
|
||||||
|
ConstexprIfsAreNotIfdefs<is_preformatted_message>::getPreformatted(LOG_IMPL_FIRST_ARG(__VA_ARGS__)).apply(_formatted_message, _format_string); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
_formatted_message = _nargs == 1 ? firstArg(__VA_ARGS__) : fmt::format(__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
std::string _file_function = __FILE__ "; "; \
|
||||||
|
_file_function += __PRETTY_FUNCTION__; \
|
||||||
|
Poco::Message _poco_message(_logger->name(), std::move(_formatted_message), \
|
||||||
|
(PRIORITY), _file_function.c_str(), __LINE__, _format_string); \
|
||||||
|
_channel->log(_poco_message); \
|
||||||
|
} \
|
||||||
|
catch (...) \
|
||||||
|
{ \
|
||||||
|
::write(STDERR_FILENO, static_cast<const void *>(MESSAGE_FOR_EXCEPTION_ON_LOGGING), sizeof(MESSAGE_FOR_EXCEPTION_ON_LOGGING)); \
|
||||||
} \
|
} \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
|
@ -52,20 +52,8 @@ static bool parseNumber(const String & description, size_t l, size_t r, size_t &
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Parse a string that generates shards and replicas. Separator - one of two characters | or ,
|
std::vector<String> parseRemoteDescription(
|
||||||
* depending on whether shards or replicas are generated.
|
const String & description, size_t l, size_t r, char separator, size_t max_addresses, const String & func_name)
|
||||||
* For example:
|
|
||||||
* host1,host2,... - generates set of shards from host1, host2, ...
|
|
||||||
* host1|host2|... - generates set of replicas from host1, host2, ...
|
|
||||||
* abc{8..10}def - generates set of shards abc8def, abc9def, abc10def.
|
|
||||||
* abc{08..10}def - generates set of shards abc08def, abc09def, abc10def.
|
|
||||||
* abc{x,yy,z}def - generates set of shards abcxdef, abcyydef, abczdef.
|
|
||||||
* abc{x|yy|z} def - generates set of replicas abcxdef, abcyydef, abczdef.
|
|
||||||
* abc{1..9}de{f,g,h} - is a direct product, 27 shards.
|
|
||||||
* abc{1..9}de{0|1} - is a direct product, 9 shards, in each 2 replicas.
|
|
||||||
*/
|
|
||||||
std::vector<String>
|
|
||||||
parseRemoteDescription(const String & description, size_t l, size_t r, char separator, size_t max_addresses, const String & func_name)
|
|
||||||
{
|
{
|
||||||
std::vector<String> res;
|
std::vector<String> res;
|
||||||
std::vector<String> cur;
|
std::vector<String> cur;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
/* Parse a string that generates shards and replicas. Separator - one of two characters | or ,
|
/* Parse a string that generates shards and replicas. Separator - one of two characters '|' or ','
|
||||||
* depending on whether shards or replicas are generated.
|
* depending on whether shards or replicas are generated.
|
||||||
* For example:
|
* For example:
|
||||||
* host1,host2,... - generates set of shards from host1, host2, ...
|
* host1,host2,... - generates set of shards from host1, host2, ...
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <Common/logger_useful.h>
|
#include <Common/logger_useful.h>
|
||||||
|
#include <Common/thread_local_rng.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <Poco/Logger.h>
|
#include <Poco/Logger.h>
|
||||||
@ -50,3 +51,55 @@ TEST(Logger, TestLog)
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t global_counter = 0;
|
||||||
|
|
||||||
|
static std::string getLogMessage()
|
||||||
|
{
|
||||||
|
++global_counter;
|
||||||
|
return "test1 " + std::to_string(thread_local_rng());
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t getLogMessageParam()
|
||||||
|
{
|
||||||
|
++global_counter;
|
||||||
|
return thread_local_rng();
|
||||||
|
}
|
||||||
|
|
||||||
|
static PreformattedMessage getPreformatted()
|
||||||
|
{
|
||||||
|
++global_counter;
|
||||||
|
return PreformattedMessage::create("test3 {}", thread_local_rng());
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t getLogMessageParamOrThrow()
|
||||||
|
{
|
||||||
|
size_t x = thread_local_rng();
|
||||||
|
if (x % 1000 == 0)
|
||||||
|
return x;
|
||||||
|
throw Poco::Exception("error", 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Logger, SideEffects)
|
||||||
|
{
|
||||||
|
std::ostringstream oss; // STYLE_CHECK_ALLOW_STD_STRING_STREAM
|
||||||
|
auto my_channel = Poco::AutoPtr<Poco::StreamChannel>(new Poco::StreamChannel(oss));
|
||||||
|
auto * log = &Poco::Logger::create("Logger", my_channel.get());
|
||||||
|
log->setLevel("trace");
|
||||||
|
|
||||||
|
/// Ensure that parameters are evaluated only once
|
||||||
|
global_counter = 0;
|
||||||
|
LOG_TRACE(log, fmt::runtime(getLogMessage()));
|
||||||
|
EXPECT_EQ(global_counter, 1);
|
||||||
|
LOG_TRACE(log, "test2 {}", getLogMessageParam());
|
||||||
|
EXPECT_EQ(global_counter, 2);
|
||||||
|
LOG_TRACE(log, getPreformatted());
|
||||||
|
EXPECT_EQ(global_counter, 3);
|
||||||
|
|
||||||
|
auto var = PreformattedMessage::create("test4 {}", thread_local_rng());
|
||||||
|
LOG_TRACE(log, var);
|
||||||
|
EXPECT_EQ(var.text.starts_with("test4 "), true);
|
||||||
|
EXPECT_EQ(var.format_string, "test4 {}");
|
||||||
|
|
||||||
|
LOG_TRACE(log, "test no throw {}", getLogMessageParamOrThrow());
|
||||||
|
}
|
||||||
|
@ -398,6 +398,14 @@ UInt32 CompressionCodecDeflateQpl::doCompressData(const char * source, UInt32 so
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void touchBufferWithZeroFilling(char * buffer, UInt32 buffer_size)
|
||||||
|
{
|
||||||
|
for (char * p = buffer; p < buffer + buffer_size; p += ::getPageSize()/(sizeof(*p)))
|
||||||
|
{
|
||||||
|
*p = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CompressionCodecDeflateQpl::doDecompressData(const char * source, UInt32 source_size, char * dest, UInt32 uncompressed_size) const
|
void CompressionCodecDeflateQpl::doDecompressData(const char * source, UInt32 source_size, char * dest, UInt32 uncompressed_size) const
|
||||||
{
|
{
|
||||||
/// QPL library is using AVX-512 with some shuffle operations.
|
/// QPL library is using AVX-512 with some shuffle operations.
|
||||||
@ -405,6 +413,10 @@ void CompressionCodecDeflateQpl::doDecompressData(const char * source, UInt32 so
|
|||||||
#if defined(MEMORY_SANITIZER)
|
#if defined(MEMORY_SANITIZER)
|
||||||
__msan_unpoison(dest, uncompressed_size);
|
__msan_unpoison(dest, uncompressed_size);
|
||||||
#endif
|
#endif
|
||||||
|
/// Device IOTLB miss has big perf. impact for IAA accelerators.
|
||||||
|
/// To avoid page fault, we need touch buffers related to accelerator in advance.
|
||||||
|
touchBufferWithZeroFilling(dest, uncompressed_size);
|
||||||
|
|
||||||
switch (getDecompressMode())
|
switch (getDecompressMode())
|
||||||
{
|
{
|
||||||
case CodecMode::Synchronous:
|
case CodecMode::Synchronous:
|
||||||
|
@ -28,6 +28,17 @@ namespace DB
|
|||||||
namespace ErrorCodes
|
namespace ErrorCodes
|
||||||
{
|
{
|
||||||
extern const int OPENSSL_ERROR;
|
extern const int OPENSSL_ERROR;
|
||||||
|
extern const int BAD_ARGUMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EncryptionMethod getEncryptionMethod(const std::string & name)
|
||||||
|
{
|
||||||
|
if (name == "AES_128_GCM_SIV")
|
||||||
|
return AES_128_GCM_SIV;
|
||||||
|
else if (name == "AES_256_GCM_SIV")
|
||||||
|
return AES_256_GCM_SIV;
|
||||||
|
else
|
||||||
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Wrong encryption method. Got {}", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -63,7 +74,7 @@ uint8_t getMethodCode(EncryptionMethod Method)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Wrong encryption Method. Got {}", getMethodName(Method));
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Wrong encryption method. Got {}", getMethodName(Method));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +90,6 @@ namespace ErrorCodes
|
|||||||
{
|
{
|
||||||
extern const int ILLEGAL_SYNTAX_FOR_CODEC_TYPE;
|
extern const int ILLEGAL_SYNTAX_FOR_CODEC_TYPE;
|
||||||
extern const int LOGICAL_ERROR;
|
extern const int LOGICAL_ERROR;
|
||||||
extern const int BAD_ARGUMENTS;
|
|
||||||
extern const int INCORRECT_DATA;
|
extern const int INCORRECT_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +114,7 @@ UInt64 methodKeySize(EncryptionMethod Method)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Wrong encryption Method. Got {}", getMethodName(Method));
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Wrong encryption method. Got {}", getMethodName(Method));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +139,7 @@ auto getMethod(EncryptionMethod Method)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Wrong encryption Method. Got {}", getMethodName(Method));
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Wrong encryption method. Got {}", getMethodName(Method));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +215,7 @@ auto getMethod(EncryptionMethod Method)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Wrong encryption Method. Got {}", getMethodName(Method));
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Wrong encryption method. Got {}", getMethodName(Method));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,7 +588,7 @@ String CompressionCodecEncrypted::Configuration::getKey(EncryptionMethod method,
|
|||||||
if (current_params->keys_storage[method].contains(key_id))
|
if (current_params->keys_storage[method].contains(key_id))
|
||||||
key = current_params->keys_storage[method].at(key_id);
|
key = current_params->keys_storage[method].at(key_id);
|
||||||
else
|
else
|
||||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "There is no key {} in config", key_id);
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "There is no key {} in config for {} encryption codec", key_id, getMethodName(method));
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ enum EncryptionMethod
|
|||||||
MAX_ENCRYPTION_METHOD
|
MAX_ENCRYPTION_METHOD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Get method for string name. Throw exception for wrong name.
|
||||||
|
EncryptionMethod getEncryptionMethod(const std::string & name);
|
||||||
|
|
||||||
/** This codec encrypts and decrypts blocks with AES-128 in
|
/** This codec encrypts and decrypts blocks with AES-128 in
|
||||||
* GCM-SIV mode (RFC-8452), which is the only cipher currently
|
* GCM-SIV mode (RFC-8452), which is the only cipher currently
|
||||||
* supported. Although it is implemented as a compression codec
|
* supported. Although it is implemented as a compression codec
|
||||||
|
@ -48,6 +48,8 @@ namespace DB
|
|||||||
M(UInt64, merges_mutations_memory_usage_soft_limit, 0, "Limit on total memory usage for merges and mutations. Zero means Unlimited.", 0) \
|
M(UInt64, merges_mutations_memory_usage_soft_limit, 0, "Limit on total memory usage for merges and mutations. Zero means Unlimited.", 0) \
|
||||||
M(Double, merges_mutations_memory_usage_to_ram_ratio, 0.5, "Same as merges_mutations_memory_usage_soft_limit but in to ram ratio. Allows to lower memory limit on low-memory systems.", 0) \
|
M(Double, merges_mutations_memory_usage_to_ram_ratio, 0.5, "Same as merges_mutations_memory_usage_soft_limit but in to ram ratio. Allows to lower memory limit on low-memory systems.", 0) \
|
||||||
M(Bool, allow_use_jemalloc_memory, true, "Allows to use jemalloc memory.", 0) \
|
M(Bool, allow_use_jemalloc_memory, true, "Allows to use jemalloc memory.", 0) \
|
||||||
|
M(UInt64, async_insert_threads, 16, "Maximum number of threads to actually parse and insert data in background. Zero means asynchronous mode is disabled", 0) \
|
||||||
|
M(Bool, async_insert_queue_flush_on_shutdown, true, "If true queue of asynchronous inserts is flushed on graceful shutdown", 0) \
|
||||||
\
|
\
|
||||||
M(UInt64, max_concurrent_queries, 0, "Limit on total number of concurrently executed queries. Zero means Unlimited.", 0) \
|
M(UInt64, max_concurrent_queries, 0, "Limit on total number of concurrently executed queries. Zero means Unlimited.", 0) \
|
||||||
M(UInt64, max_concurrent_insert_queries, 0, "Limit on total number of concurrently insert queries. Zero means Unlimited.", 0) \
|
M(UInt64, max_concurrent_insert_queries, 0, "Limit on total number of concurrently insert queries. Zero means Unlimited.", 0) \
|
||||||
|
@ -534,7 +534,6 @@ class IColumn;
|
|||||||
M(Bool, convert_query_to_cnf, false, "Convert SELECT query to CNF", 0) \
|
M(Bool, convert_query_to_cnf, false, "Convert SELECT query to CNF", 0) \
|
||||||
M(Bool, optimize_or_like_chain, false, "Optimize multiple OR LIKE into multiMatchAny. This optimization should not be enabled by default, because it defies index analysis in some cases.", 0) \
|
M(Bool, optimize_or_like_chain, false, "Optimize multiple OR LIKE into multiMatchAny. This optimization should not be enabled by default, because it defies index analysis in some cases.", 0) \
|
||||||
M(Bool, optimize_arithmetic_operations_in_aggregate_functions, true, "Move arithmetic operations out of aggregation functions", 0) \
|
M(Bool, optimize_arithmetic_operations_in_aggregate_functions, true, "Move arithmetic operations out of aggregation functions", 0) \
|
||||||
M(Bool, optimize_duplicate_order_by_and_distinct, false, "Remove duplicate ORDER BY and DISTINCT if it's possible", 0) \
|
|
||||||
M(Bool, optimize_redundant_functions_in_order_by, true, "Remove functions from ORDER BY if its argument is also in ORDER BY", 0) \
|
M(Bool, optimize_redundant_functions_in_order_by, true, "Remove functions from ORDER BY if its argument is also in ORDER BY", 0) \
|
||||||
M(Bool, optimize_if_chain_to_multiif, false, "Replace if(cond1, then1, if(cond2, ...)) chains to multiIf. Currently it's not beneficial for numeric types.", 0) \
|
M(Bool, optimize_if_chain_to_multiif, false, "Replace if(cond1, then1, if(cond2, ...)) chains to multiIf. Currently it's not beneficial for numeric types.", 0) \
|
||||||
M(Bool, optimize_multiif_to_if, true, "Replace 'multiIf' with only one condition to 'if'.", 0) \
|
M(Bool, optimize_multiif_to_if, true, "Replace 'multiIf' with only one condition to 'if'.", 0) \
|
||||||
@ -623,6 +622,7 @@ class IColumn;
|
|||||||
M(Bool, engine_file_allow_create_multiple_files, false, "Enables or disables creating a new file on each insert in file engine tables if format has suffix.", 0) \
|
M(Bool, engine_file_allow_create_multiple_files, false, "Enables or disables creating a new file on each insert in file engine tables if format has suffix.", 0) \
|
||||||
M(Bool, engine_file_skip_empty_files, false, "Allows to skip empty files in file table engine", 0) \
|
M(Bool, engine_file_skip_empty_files, false, "Allows to skip empty files in file table engine", 0) \
|
||||||
M(Bool, engine_url_skip_empty_files, false, "Allows to skip empty files in url table engine", 0) \
|
M(Bool, engine_url_skip_empty_files, false, "Allows to skip empty files in url table engine", 0) \
|
||||||
|
M(Bool, disable_url_encoding, false, " Allows to disable decoding/encoding path in uri in URL table engine", 0) \
|
||||||
M(Bool, allow_experimental_database_replicated, false, "Allow to create databases with Replicated engine", 0) \
|
M(Bool, allow_experimental_database_replicated, false, "Allow to create databases with Replicated engine", 0) \
|
||||||
M(UInt64, database_replicated_initial_query_timeout_sec, 300, "How long initial DDL query should wait for Replicated database to precess previous DDL queue entries", 0) \
|
M(UInt64, database_replicated_initial_query_timeout_sec, 300, "How long initial DDL query should wait for Replicated database to precess previous DDL queue entries", 0) \
|
||||||
M(Bool, database_replicated_enforce_synchronous_settings, false, "Enforces synchronous waiting for some queries (see also database_atomic_wait_for_drop_and_detach_synchronously, mutation_sync, alter_sync). Not recommended to enable these settings.", 0) \
|
M(Bool, database_replicated_enforce_synchronous_settings, false, "Enforces synchronous waiting for some queries (see also database_atomic_wait_for_drop_and_detach_synchronously, mutation_sync, alter_sync). Not recommended to enable these settings.", 0) \
|
||||||
@ -659,7 +659,8 @@ class IColumn;
|
|||||||
M(UInt64, limit, 0, "Limit on read rows from the most 'end' result for select query, default 0 means no limit length", 0) \
|
M(UInt64, limit, 0, "Limit on read rows from the most 'end' result for select query, default 0 means no limit length", 0) \
|
||||||
M(UInt64, offset, 0, "Offset on read rows from the most 'end' result for select query", 0) \
|
M(UInt64, offset, 0, "Offset on read rows from the most 'end' result for select query", 0) \
|
||||||
\
|
\
|
||||||
M(UInt64, function_range_max_elements_in_block, 500000000, "Maximum number of values generated by function 'range' per block of data (sum of array sizes for every row in a block, see also 'max_block_size' and 'min_insert_block_size_rows'). It is a safety threshold.", 0) \
|
M(UInt64, function_range_max_elements_in_block, 500000000, "Maximum number of values generated by function `range` per block of data (sum of array sizes for every row in a block, see also 'max_block_size' and 'min_insert_block_size_rows'). It is a safety threshold.", 0) \
|
||||||
|
M(UInt64, function_sleep_max_microseconds_per_block, 3000000, "Maximum number of microseconds the function `sleep` is allowed to sleep for each block. If a user called it with a larger value, it throws an exception. It is a safety threshold.", 0) \
|
||||||
M(ShortCircuitFunctionEvaluation, short_circuit_function_evaluation, ShortCircuitFunctionEvaluation::ENABLE, "Setting for short-circuit function evaluation configuration. Possible values: 'enable' - use short-circuit function evaluation for functions that are suitable for it, 'disable' - disable short-circuit function evaluation, 'force_enable' - use short-circuit function evaluation for all functions.", 0) \
|
M(ShortCircuitFunctionEvaluation, short_circuit_function_evaluation, ShortCircuitFunctionEvaluation::ENABLE, "Setting for short-circuit function evaluation configuration. Possible values: 'enable' - use short-circuit function evaluation for functions that are suitable for it, 'disable' - disable short-circuit function evaluation, 'force_enable' - use short-circuit function evaluation for all functions.", 0) \
|
||||||
\
|
\
|
||||||
M(LocalFSReadMethod, storage_file_read_method, LocalFSReadMethod::pread, "Method of reading data from storage file, one of: read, pread, mmap. The mmap method does not apply to clickhouse-server (it's intended for clickhouse-local).", 0) \
|
M(LocalFSReadMethod, storage_file_read_method, LocalFSReadMethod::pread, "Method of reading data from storage file, one of: read, pread, mmap. The mmap method does not apply to clickhouse-server (it's intended for clickhouse-local).", 0) \
|
||||||
@ -673,8 +674,8 @@ class IColumn;
|
|||||||
M(UInt64, remote_read_min_bytes_for_seek, 4 * DBMS_DEFAULT_BUFFER_SIZE, "Min bytes required for remote read (url, s3) to do seek, instead of read with ignore.", 0) \
|
M(UInt64, remote_read_min_bytes_for_seek, 4 * DBMS_DEFAULT_BUFFER_SIZE, "Min bytes required for remote read (url, s3) to do seek, instead of read with ignore.", 0) \
|
||||||
M(UInt64, merge_tree_min_bytes_per_task_for_remote_reading, 4 * DBMS_DEFAULT_BUFFER_SIZE, "Min bytes to read per task.", 0) \
|
M(UInt64, merge_tree_min_bytes_per_task_for_remote_reading, 4 * DBMS_DEFAULT_BUFFER_SIZE, "Min bytes to read per task.", 0) \
|
||||||
M(Bool, merge_tree_use_const_size_tasks_for_remote_reading, true, "Whether to use constant size tasks for reading from a remote table.", 0) \
|
M(Bool, merge_tree_use_const_size_tasks_for_remote_reading, true, "Whether to use constant size tasks for reading from a remote table.", 0) \
|
||||||
|
M(Bool, merge_tree_determine_task_size_by_prewhere_columns, true, "Whether to use only prewhere columns size to determine reading task size.", 0) \
|
||||||
\
|
\
|
||||||
M(UInt64, async_insert_threads, 16, "Maximum number of threads to actually parse and insert data in background. Zero means asynchronous mode is disabled", 0) \
|
|
||||||
M(Bool, async_insert, false, "If true, data from INSERT query is stored in queue and later flushed to table in background. If wait_for_async_insert is false, INSERT query is processed almost instantly, otherwise client will wait until data will be flushed to table", 0) \
|
M(Bool, async_insert, false, "If true, data from INSERT query is stored in queue and later flushed to table in background. If wait_for_async_insert is false, INSERT query is processed almost instantly, otherwise client will wait until data will be flushed to table", 0) \
|
||||||
M(Bool, wait_for_async_insert, true, "If true wait for processing of asynchronous insertion", 0) \
|
M(Bool, wait_for_async_insert, true, "If true wait for processing of asynchronous insertion", 0) \
|
||||||
M(Seconds, wait_for_async_insert_timeout, DBMS_DEFAULT_LOCK_ACQUIRE_TIMEOUT_SEC, "Timeout for waiting for processing asynchronous insertion", 0) \
|
M(Seconds, wait_for_async_insert_timeout, DBMS_DEFAULT_LOCK_ACQUIRE_TIMEOUT_SEC, "Timeout for waiting for processing asynchronous insertion", 0) \
|
||||||
@ -820,6 +821,7 @@ class IColumn;
|
|||||||
MAKE_DEPRECATED_BY_SERVER_CONFIG(M, UInt64, background_distributed_schedule_pool_size, 16) \
|
MAKE_DEPRECATED_BY_SERVER_CONFIG(M, UInt64, background_distributed_schedule_pool_size, 16) \
|
||||||
MAKE_DEPRECATED_BY_SERVER_CONFIG(M, UInt64, max_remote_read_network_bandwidth_for_server, 0) \
|
MAKE_DEPRECATED_BY_SERVER_CONFIG(M, UInt64, max_remote_read_network_bandwidth_for_server, 0) \
|
||||||
MAKE_DEPRECATED_BY_SERVER_CONFIG(M, UInt64, max_remote_write_network_bandwidth_for_server, 0) \
|
MAKE_DEPRECATED_BY_SERVER_CONFIG(M, UInt64, max_remote_write_network_bandwidth_for_server, 0) \
|
||||||
|
MAKE_DEPRECATED_BY_SERVER_CONFIG(M, UInt64, async_insert_threads, 16) \
|
||||||
MAKE_DEPRECATED_BY_SERVER_CONFIG(M, UInt64, max_replicated_fetches_network_bandwidth_for_server, 0) \
|
MAKE_DEPRECATED_BY_SERVER_CONFIG(M, UInt64, max_replicated_fetches_network_bandwidth_for_server, 0) \
|
||||||
MAKE_DEPRECATED_BY_SERVER_CONFIG(M, UInt64, max_replicated_sends_network_bandwidth_for_server, 0) \
|
MAKE_DEPRECATED_BY_SERVER_CONFIG(M, UInt64, max_replicated_sends_network_bandwidth_for_server, 0) \
|
||||||
/* ---- */ \
|
/* ---- */ \
|
||||||
@ -831,6 +833,7 @@ class IColumn;
|
|||||||
MAKE_OBSOLETE(M, Seconds, drain_timeout, 3) \
|
MAKE_OBSOLETE(M, Seconds, drain_timeout, 3) \
|
||||||
MAKE_OBSOLETE(M, UInt64, backup_threads, 16) \
|
MAKE_OBSOLETE(M, UInt64, backup_threads, 16) \
|
||||||
MAKE_OBSOLETE(M, UInt64, restore_threads, 16) \
|
MAKE_OBSOLETE(M, UInt64, restore_threads, 16) \
|
||||||
|
MAKE_OBSOLETE(M, Bool, optimize_duplicate_order_by_and_distinct, false) \
|
||||||
|
|
||||||
/** The section above is for obsolete settings. Do not add anything there. */
|
/** The section above is for obsolete settings. Do not add anything there. */
|
||||||
|
|
||||||
@ -951,6 +954,10 @@ class IColumn;
|
|||||||
M(ParquetVersion, output_format_parquet_version, "2.latest", "Parquet format version for output format. Supported versions: 1.0, 2.4, 2.6 and 2.latest (default)", 0) \
|
M(ParquetVersion, output_format_parquet_version, "2.latest", "Parquet format version for output format. Supported versions: 1.0, 2.4, 2.6 and 2.latest (default)", 0) \
|
||||||
M(ParquetCompression, output_format_parquet_compression_method, "lz4", "Compression method for Parquet output format. Supported codecs: snappy, lz4, brotli, zstd, gzip, none (uncompressed)", 0) \
|
M(ParquetCompression, output_format_parquet_compression_method, "lz4", "Compression method for Parquet output format. Supported codecs: snappy, lz4, brotli, zstd, gzip, none (uncompressed)", 0) \
|
||||||
M(Bool, output_format_parquet_compliant_nested_types, true, "In parquet file schema, use name 'element' instead of 'item' for list elements. This is a historical artifact of Arrow library implementation. Generally increases compatibility, except perhaps with some old versions of Arrow.", 0) \
|
M(Bool, output_format_parquet_compliant_nested_types, true, "In parquet file schema, use name 'element' instead of 'item' for list elements. This is a historical artifact of Arrow library implementation. Generally increases compatibility, except perhaps with some old versions of Arrow.", 0) \
|
||||||
|
M(Bool, output_format_parquet_use_custom_encoder, true, "Use experimental faster Parquet encoder implementation.", 0) \
|
||||||
|
M(Bool, output_format_parquet_parallel_encoding, true, "Do Parquet encoding in multiple threads. Requires output_format_parquet_use_custom_encoder.", 0) \
|
||||||
|
M(UInt64, output_format_parquet_data_page_size, 1024 * 1024, "Target page size in bytes, before compression.", 0) \
|
||||||
|
M(UInt64, output_format_parquet_batch_size, 1024, "Check page size every this many rows. Consider decreasing if you have columns with average values size above a few KBs.", 0) \
|
||||||
M(String, output_format_avro_codec, "", "Compression codec used for output. Possible values: 'null', 'deflate', 'snappy'.", 0) \
|
M(String, output_format_avro_codec, "", "Compression codec used for output. Possible values: 'null', 'deflate', 'snappy'.", 0) \
|
||||||
M(UInt64, output_format_avro_sync_interval, 16 * 1024, "Sync interval in bytes.", 0) \
|
M(UInt64, output_format_avro_sync_interval, 16 * 1024, "Sync interval in bytes.", 0) \
|
||||||
M(String, output_format_avro_string_column_pattern, "", "For Avro format: regexp of String columns to select as AVRO string.", 0) \
|
M(String, output_format_avro_string_column_pattern, "", "For Avro format: regexp of String columns to select as AVRO string.", 0) \
|
||||||
|
@ -80,6 +80,7 @@ namespace SettingsChangesHistory
|
|||||||
/// It's used to implement `compatibility` setting (see https://github.com/ClickHouse/ClickHouse/issues/35972)
|
/// It's used to implement `compatibility` setting (see https://github.com/ClickHouse/ClickHouse/issues/35972)
|
||||||
static std::map<ClickHouseVersion, SettingsChangesHistory::SettingsChanges> settings_changes_history =
|
static std::map<ClickHouseVersion, SettingsChangesHistory::SettingsChanges> settings_changes_history =
|
||||||
{
|
{
|
||||||
|
{"23.7", {{"function_sleep_max_microseconds_per_block", 0, 3000000, "In previous versions, the maximum sleep time of 3 seconds was applied only for `sleep`, but not for `sleepEachRow` function. In the new version, we introduce this setting. If you set compatibility with the previous versions, we will disable the limit altogether."}}},
|
||||||
{"23.6", {{"http_send_timeout", 180, 30, "3 minutes seems crazy long. Note that this is timeout for a single network write call, not for the whole upload operation."},
|
{"23.6", {{"http_send_timeout", 180, 30, "3 minutes seems crazy long. Note that this is timeout for a single network write call, not for the whole upload operation."},
|
||||||
{"http_receive_timeout", 180, 30, "See http_send_timeout."}}},
|
{"http_receive_timeout", 180, 30, "See http_send_timeout."}}},
|
||||||
{"23.5", {{"input_format_parquet_preserve_order", true, false, "Allow Parquet reader to reorder rows for better parallelism."},
|
{"23.5", {{"input_format_parquet_preserve_order", true, false, "Allow Parquet reader to reorder rows for better parallelism."},
|
||||||
|
@ -121,7 +121,7 @@ GTEST_TEST(SettingMySQLDataTypesSupport, SetString)
|
|||||||
ASSERT_EQ(Field("decimal,datetime64"), setting);
|
ASSERT_EQ(Field("decimal,datetime64"), setting);
|
||||||
|
|
||||||
// comma with spaces
|
// comma with spaces
|
||||||
setting = " datetime64 , decimal ";
|
setting = " datetime64 , decimal "; /// bad punctuation is ok here
|
||||||
ASSERT_TRUE(setting.changed);
|
ASSERT_TRUE(setting.changed);
|
||||||
ASSERT_TRUE(setting.value.isSet(MySQLDataTypesSupport::DECIMAL));
|
ASSERT_TRUE(setting.value.isSet(MySQLDataTypesSupport::DECIMAL));
|
||||||
ASSERT_TRUE(setting.value.isSet(MySQLDataTypesSupport::DATETIME64));
|
ASSERT_TRUE(setting.value.isSet(MySQLDataTypesSupport::DATETIME64));
|
||||||
@ -166,4 +166,3 @@ GTEST_TEST(SettingMySQLDataTypesSupport, SetInvalidString)
|
|||||||
ASSERT_TRUE(setting.changed);
|
ASSERT_TRUE(setting.changed);
|
||||||
ASSERT_EQ(0, setting.value.getValue());
|
ASSERT_EQ(0, setting.value.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,6 +524,7 @@ void DatabaseReplicated::startupTables(ThreadPool & thread_pool, LoadingStrictne
|
|||||||
|
|
||||||
ddl_worker = std::make_unique<DatabaseReplicatedDDLWorker>(this, getContext());
|
ddl_worker = std::make_unique<DatabaseReplicatedDDLWorker>(this, getContext());
|
||||||
ddl_worker->startup();
|
ddl_worker->startup();
|
||||||
|
ddl_worker_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseReplicated::checkDigestValid(const ContextPtr & local_context, bool debug_check /* = true */) const
|
bool DatabaseReplicated::checkDigestValid(const ContextPtr & local_context, bool debug_check /* = true */) const
|
||||||
@ -1155,6 +1156,7 @@ void DatabaseReplicated::stopReplication()
|
|||||||
void DatabaseReplicated::shutdown()
|
void DatabaseReplicated::shutdown()
|
||||||
{
|
{
|
||||||
stopReplication();
|
stopReplication();
|
||||||
|
ddl_worker_initialized = false;
|
||||||
ddl_worker = nullptr;
|
ddl_worker = nullptr;
|
||||||
DatabaseAtomic::shutdown();
|
DatabaseAtomic::shutdown();
|
||||||
}
|
}
|
||||||
@ -1299,7 +1301,7 @@ bool DatabaseReplicated::canExecuteReplicatedMetadataAlter() const
|
|||||||
/// It may update the metadata digest (both locally and in ZooKeeper)
|
/// It may update the metadata digest (both locally and in ZooKeeper)
|
||||||
/// before DatabaseReplicatedDDLWorker::initializeReplication() has finished.
|
/// before DatabaseReplicatedDDLWorker::initializeReplication() has finished.
|
||||||
/// We should not update metadata until the database is initialized.
|
/// We should not update metadata until the database is initialized.
|
||||||
return ddl_worker && ddl_worker->isCurrentlyActive();
|
return ddl_worker_initialized && ddl_worker->isCurrentlyActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseReplicated::detachTablePermanently(ContextPtr local_context, const String & table_name)
|
void DatabaseReplicated::detachTablePermanently(ContextPtr local_context, const String & table_name)
|
||||||
|
@ -134,6 +134,7 @@ private:
|
|||||||
std::atomic_bool is_readonly = true;
|
std::atomic_bool is_readonly = true;
|
||||||
std::atomic_bool is_probably_dropped = false;
|
std::atomic_bool is_probably_dropped = false;
|
||||||
std::atomic_bool is_recovering = false;
|
std::atomic_bool is_recovering = false;
|
||||||
|
std::atomic_bool ddl_worker_initialized = false;
|
||||||
std::unique_ptr<DatabaseReplicatedDDLWorker> ddl_worker;
|
std::unique_ptr<DatabaseReplicatedDDLWorker> ddl_worker;
|
||||||
UInt32 max_log_ptr_at_creation = 0;
|
UInt32 max_log_ptr_at_creation = 0;
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@ void DatabaseWithOwnTablesBase::shutdown()
|
|||||||
|
|
||||||
for (const auto & kv : tables_snapshot)
|
for (const auto & kv : tables_snapshot)
|
||||||
{
|
{
|
||||||
kv.second->flush();
|
kv.second->flushAndPrepareForShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto & kv : tables_snapshot)
|
for (const auto & kv : tables_snapshot)
|
||||||
|
@ -34,7 +34,9 @@ enum class AttributeUnderlyingType : TypeIndexUnderlying
|
|||||||
map_item(Decimal32), map_item(Decimal64), map_item(Decimal128), map_item(Decimal256),
|
map_item(Decimal32), map_item(Decimal64), map_item(Decimal128), map_item(Decimal256),
|
||||||
map_item(DateTime64),
|
map_item(DateTime64),
|
||||||
|
|
||||||
map_item(UUID), map_item(String), map_item(Array)
|
map_item(UUID), map_item(String), map_item(Array),
|
||||||
|
|
||||||
|
map_item(IPv4), map_item(IPv6)
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef map_item
|
#undef map_item
|
||||||
|
@ -130,6 +130,10 @@ FormatSettings getFormatSettings(ContextPtr context, const Settings & settings)
|
|||||||
format_settings.parquet.max_block_size = settings.input_format_parquet_max_block_size;
|
format_settings.parquet.max_block_size = settings.input_format_parquet_max_block_size;
|
||||||
format_settings.parquet.output_compression_method = settings.output_format_parquet_compression_method;
|
format_settings.parquet.output_compression_method = settings.output_format_parquet_compression_method;
|
||||||
format_settings.parquet.output_compliant_nested_types = settings.output_format_parquet_compliant_nested_types;
|
format_settings.parquet.output_compliant_nested_types = settings.output_format_parquet_compliant_nested_types;
|
||||||
|
format_settings.parquet.use_custom_encoder = settings.output_format_parquet_use_custom_encoder;
|
||||||
|
format_settings.parquet.parallel_encoding = settings.output_format_parquet_parallel_encoding;
|
||||||
|
format_settings.parquet.data_page_size = settings.output_format_parquet_data_page_size;
|
||||||
|
format_settings.parquet.write_batch_size = settings.output_format_parquet_batch_size;
|
||||||
format_settings.pretty.charset = settings.output_format_pretty_grid_charset.toString() == "ASCII" ? FormatSettings::Pretty::Charset::ASCII : FormatSettings::Pretty::Charset::UTF8;
|
format_settings.pretty.charset = settings.output_format_pretty_grid_charset.toString() == "ASCII" ? FormatSettings::Pretty::Charset::ASCII : FormatSettings::Pretty::Charset::UTF8;
|
||||||
format_settings.pretty.color = settings.output_format_pretty_color;
|
format_settings.pretty.color = settings.output_format_pretty_color;
|
||||||
format_settings.pretty.max_column_pad_width = settings.output_format_pretty_max_column_pad_width;
|
format_settings.pretty.max_column_pad_width = settings.output_format_pretty_max_column_pad_width;
|
||||||
@ -434,7 +438,7 @@ OutputFormatPtr FormatFactory::getOutputFormatParallelIfPossible(
|
|||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getOutputFormat(name, buf, sample, context, _format_settings);
|
return getOutputFormat(name, buf, sample, context, format_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -453,6 +457,7 @@ OutputFormatPtr FormatFactory::getOutputFormat(
|
|||||||
context->getQueryContext()->addQueryFactoriesInfo(Context::QueryLogFactories::Format, name);
|
context->getQueryContext()->addQueryFactoriesInfo(Context::QueryLogFactories::Format, name);
|
||||||
|
|
||||||
auto format_settings = _format_settings ? *_format_settings : getFormatSettings(context);
|
auto format_settings = _format_settings ? *_format_settings : getFormatSettings(context);
|
||||||
|
format_settings.max_threads = context->getSettingsRef().max_threads;
|
||||||
|
|
||||||
/** TODO: Materialization is needed, because formats can use the functions `IDataType`,
|
/** TODO: Materialization is needed, because formats can use the functions `IDataType`,
|
||||||
* which only work with full columns.
|
* which only work with full columns.
|
||||||
|
@ -100,6 +100,8 @@ struct FormatSettings
|
|||||||
|
|
||||||
UInt64 max_parser_depth = DBMS_DEFAULT_MAX_PARSER_DEPTH;
|
UInt64 max_parser_depth = DBMS_DEFAULT_MAX_PARSER_DEPTH;
|
||||||
|
|
||||||
|
size_t max_threads = 1;
|
||||||
|
|
||||||
enum class ArrowCompression
|
enum class ArrowCompression
|
||||||
{
|
{
|
||||||
NONE,
|
NONE,
|
||||||
@ -233,10 +235,14 @@ struct FormatSettings
|
|||||||
bool output_string_as_string = false;
|
bool output_string_as_string = false;
|
||||||
bool output_fixed_string_as_fixed_byte_array = true;
|
bool output_fixed_string_as_fixed_byte_array = true;
|
||||||
bool preserve_order = false;
|
bool preserve_order = false;
|
||||||
|
bool use_custom_encoder = true;
|
||||||
|
bool parallel_encoding = true;
|
||||||
UInt64 max_block_size = 8192;
|
UInt64 max_block_size = 8192;
|
||||||
ParquetVersion output_version;
|
ParquetVersion output_version;
|
||||||
ParquetCompression output_compression_method = ParquetCompression::SNAPPY;
|
ParquetCompression output_compression_method = ParquetCompression::SNAPPY;
|
||||||
bool output_compliant_nested_types = true;
|
bool output_compliant_nested_types = true;
|
||||||
|
size_t data_page_size = 1024 * 1024;
|
||||||
|
size_t write_batch_size = 1024;
|
||||||
} parquet;
|
} parquet;
|
||||||
|
|
||||||
struct Pretty
|
struct Pretty
|
||||||
|
22
src/Functions/FunctionToDecimalString.cpp
Normal file
22
src/Functions/FunctionToDecimalString.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <Functions/FunctionFactory.h>
|
||||||
|
#include <Functions/FunctionToDecimalString.h>
|
||||||
|
#include <Functions/IFunction.h>
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
REGISTER_FUNCTION(ToDecimalString)
|
||||||
|
{
|
||||||
|
factory.registerFunction<FunctionToDecimalString>(
|
||||||
|
FunctionDocumentation{
|
||||||
|
.description=R"(
|
||||||
|
Returns string representation of a number. First argument is the number of any numeric type,
|
||||||
|
second argument is the desired number of digits in fractional part. Returns String.
|
||||||
|
|
||||||
|
)",
|
||||||
|
.examples{{"toDecimalString", "SELECT toDecimalString(2.1456,2)", ""}},
|
||||||
|
.categories{"String"}
|
||||||
|
}, FunctionFactory::CaseInsensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
262
src/Functions/FunctionToDecimalString.h
Normal file
262
src/Functions/FunctionToDecimalString.h
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Core/Types.h>
|
||||||
|
#include <Core/DecimalFunctions.h>
|
||||||
|
#include <Functions/IFunction.h>
|
||||||
|
#include <Functions/FunctionHelpers.h>
|
||||||
|
#include <Columns/ColumnsNumber.h>
|
||||||
|
#include <Columns/ColumnString.h>
|
||||||
|
#include <Columns/ColumnVector.h>
|
||||||
|
#include <Columns/ColumnDecimal.h>
|
||||||
|
#include <DataTypes/DataTypeString.h>
|
||||||
|
#include <DataTypes/DataTypesNumber.h>
|
||||||
|
#include <IO/WriteBufferFromVector.h>
|
||||||
|
#include <IO/WriteHelpers.h>
|
||||||
|
#include <Interpreters/Context_fwd.h>
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace ErrorCodes
|
||||||
|
{
|
||||||
|
extern const int ILLEGAL_COLUMN;
|
||||||
|
extern const int CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER;
|
||||||
|
}
|
||||||
|
|
||||||
|
class FunctionToDecimalString : public IFunction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr auto name = "toDecimalString";
|
||||||
|
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionToDecimalString>(); }
|
||||||
|
|
||||||
|
String getName() const override { return name; }
|
||||||
|
|
||||||
|
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return true; }
|
||||||
|
|
||||||
|
size_t getNumberOfArguments() const override { return 2; }
|
||||||
|
|
||||||
|
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||||
|
{
|
||||||
|
FunctionArgumentDescriptors mandatory_args = {
|
||||||
|
{"Value", &isNumber<IDataType>, nullptr, "Number"},
|
||||||
|
{"precision", &isNativeInteger<IDataType>, &isColumnConst, "const Integer"}
|
||||||
|
};
|
||||||
|
|
||||||
|
validateFunctionArgumentTypes(*this, arguments, mandatory_args, {});
|
||||||
|
|
||||||
|
return std::make_shared<DataTypeString>();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool useDefaultImplementationForConstants() const override { return true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// For operations with Integer/Float
|
||||||
|
template <typename FromVectorType>
|
||||||
|
void vectorConstant(const FromVectorType & vec_from, UInt8 precision,
|
||||||
|
ColumnString::Chars & vec_to, ColumnString::Offsets & result_offsets) const
|
||||||
|
{
|
||||||
|
size_t input_rows_count = vec_from.size();
|
||||||
|
result_offsets.resize(input_rows_count);
|
||||||
|
|
||||||
|
/// Buffer is used here and in functions below because resulting size cannot be precisely anticipated,
|
||||||
|
/// and buffer resizes on-the-go. Also, .count() provided by buffer is convenient in this case.
|
||||||
|
WriteBufferFromVector<ColumnString::Chars> buf_to(vec_to);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < input_rows_count; ++i)
|
||||||
|
{
|
||||||
|
format(vec_from[i], buf_to, precision);
|
||||||
|
result_offsets[i] = buf_to.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_to.finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FirstArgVectorType>
|
||||||
|
void vectorVector(const FirstArgVectorType & vec_from, const ColumnVector<UInt8>::Container & vec_precision,
|
||||||
|
ColumnString::Chars & vec_to, ColumnString::Offsets & result_offsets) const
|
||||||
|
{
|
||||||
|
size_t input_rows_count = vec_from.size();
|
||||||
|
result_offsets.resize(input_rows_count);
|
||||||
|
|
||||||
|
WriteBufferFromVector<ColumnString::Chars> buf_to(vec_to);
|
||||||
|
|
||||||
|
constexpr size_t max_digits = std::numeric_limits<UInt256>::digits10;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < input_rows_count; ++i)
|
||||||
|
{
|
||||||
|
if (vec_precision[i] > max_digits)
|
||||||
|
throw DB::Exception(DB::ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER,
|
||||||
|
"Too many fractional digits requested, shall not be more than {}", max_digits);
|
||||||
|
format(vec_from[i], buf_to, vec_precision[i]);
|
||||||
|
result_offsets[i] = buf_to.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_to.finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For operations with Decimal
|
||||||
|
template <typename FirstArgVectorType>
|
||||||
|
void vectorConstant(const FirstArgVectorType & vec_from, UInt8 precision,
|
||||||
|
ColumnString::Chars & vec_to, ColumnString::Offsets & result_offsets, UInt8 from_scale) const
|
||||||
|
{
|
||||||
|
/// There are no more than 77 meaning digits (as it is the max length of UInt256). So we can limit it with 77.
|
||||||
|
constexpr size_t max_digits = std::numeric_limits<UInt256>::digits10;
|
||||||
|
if (precision > max_digits)
|
||||||
|
throw DB::Exception(DB::ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER,
|
||||||
|
"Too many fractional digits requested for Decimal, must not be more than {}", max_digits);
|
||||||
|
|
||||||
|
WriteBufferFromVector<ColumnString::Chars> buf_to(vec_to);
|
||||||
|
size_t input_rows_count = vec_from.size();
|
||||||
|
result_offsets.resize(input_rows_count);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < input_rows_count; ++i)
|
||||||
|
{
|
||||||
|
writeText(vec_from[i], from_scale, buf_to, true, true, precision);
|
||||||
|
writeChar(0, buf_to);
|
||||||
|
result_offsets[i] = buf_to.count();
|
||||||
|
}
|
||||||
|
buf_to.finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FirstArgVectorType>
|
||||||
|
void vectorVector(const FirstArgVectorType & vec_from, const ColumnVector<UInt8>::Container & vec_precision,
|
||||||
|
ColumnString::Chars & vec_to, ColumnString::Offsets & result_offsets, UInt8 from_scale) const
|
||||||
|
{
|
||||||
|
size_t input_rows_count = vec_from.size();
|
||||||
|
result_offsets.resize(input_rows_count);
|
||||||
|
|
||||||
|
WriteBufferFromVector<ColumnString::Chars> buf_to(vec_to);
|
||||||
|
|
||||||
|
constexpr size_t max_digits = std::numeric_limits<UInt256>::digits10;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < input_rows_count; ++i)
|
||||||
|
{
|
||||||
|
if (vec_precision[i] > max_digits)
|
||||||
|
throw DB::Exception(DB::ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER,
|
||||||
|
"Too many fractional digits requested for Decimal, must not be more than {}", max_digits);
|
||||||
|
writeText(vec_from[i], from_scale, buf_to, true, true, vec_precision[i]);
|
||||||
|
writeChar(0, buf_to);
|
||||||
|
result_offsets[i] = buf_to.count();
|
||||||
|
}
|
||||||
|
buf_to.finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <is_floating_point T>
|
||||||
|
static void format(T value, DB::WriteBuffer & out, UInt8 precision)
|
||||||
|
{
|
||||||
|
/// Maximum of 60 is hard-coded in 'double-conversion/double-conversion.h' for floating point values,
|
||||||
|
/// Catch this here to give user a more reasonable error.
|
||||||
|
if (precision > 60)
|
||||||
|
throw DB::Exception(DB::ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER,
|
||||||
|
"Too high precision requested for Float, must not be more than 60, got {}", Int8(precision));
|
||||||
|
|
||||||
|
DB::DoubleConverter<false>::BufferType buffer;
|
||||||
|
double_conversion::StringBuilder builder{buffer, sizeof(buffer)};
|
||||||
|
|
||||||
|
const auto result = DB::DoubleConverter<false>::instance().ToFixed(value, precision, &builder);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
throw DB::Exception(DB::ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER, "Error processing number: {}", value);
|
||||||
|
|
||||||
|
out.write(buffer, builder.position());
|
||||||
|
writeChar(0, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <is_integer T>
|
||||||
|
static void format(T value, DB::WriteBuffer & out, UInt8 precision)
|
||||||
|
{
|
||||||
|
/// Fractional part for Integer is just trailing zeros. Let's limit it with 77 (like with Decimals).
|
||||||
|
constexpr size_t max_digits = std::numeric_limits<UInt256>::digits10;
|
||||||
|
if (precision > max_digits)
|
||||||
|
throw DB::Exception(DB::ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER,
|
||||||
|
"Too many fractional digits requested, shall not be more than {}", max_digits);
|
||||||
|
writeText(value, out);
|
||||||
|
if (precision > 0) [[likely]]
|
||||||
|
{
|
||||||
|
writeChar('.', out);
|
||||||
|
for (int i = 0; i < precision; ++i)
|
||||||
|
writeChar('0', out);
|
||||||
|
writeChar(0, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
|
||||||
|
{
|
||||||
|
switch (arguments[0].type->getTypeId())
|
||||||
|
{
|
||||||
|
case TypeIndex::UInt8: return executeType<UInt8>(arguments);
|
||||||
|
case TypeIndex::UInt16: return executeType<UInt16>(arguments);
|
||||||
|
case TypeIndex::UInt32: return executeType<UInt32>(arguments);
|
||||||
|
case TypeIndex::UInt64: return executeType<UInt64>(arguments);
|
||||||
|
case TypeIndex::UInt128: return executeType<UInt128>(arguments);
|
||||||
|
case TypeIndex::UInt256: return executeType<UInt256>(arguments);
|
||||||
|
case TypeIndex::Int8: return executeType<Int8>(arguments);
|
||||||
|
case TypeIndex::Int16: return executeType<Int16>(arguments);
|
||||||
|
case TypeIndex::Int32: return executeType<Int32>(arguments);
|
||||||
|
case TypeIndex::Int64: return executeType<Int64>(arguments);
|
||||||
|
case TypeIndex::Int128: return executeType<Int128>(arguments);
|
||||||
|
case TypeIndex::Int256: return executeType<Int256>(arguments);
|
||||||
|
case TypeIndex::Float32: return executeType<Float32>(arguments);
|
||||||
|
case TypeIndex::Float64: return executeType<Float64>(arguments);
|
||||||
|
case TypeIndex::Decimal32: return executeType<Decimal32>(arguments);
|
||||||
|
case TypeIndex::Decimal64: return executeType<Decimal64>(arguments);
|
||||||
|
case TypeIndex::Decimal128: return executeType<Decimal128>(arguments);
|
||||||
|
case TypeIndex::Decimal256: return executeType<Decimal256>(arguments);
|
||||||
|
default:
|
||||||
|
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of argument of function {}",
|
||||||
|
arguments[0].column->getName(), getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T>
|
||||||
|
ColumnPtr executeType(const ColumnsWithTypeAndName & arguments) const
|
||||||
|
{
|
||||||
|
const auto * precision_col = checkAndGetColumn<ColumnVector<UInt8>>(arguments[1].column.get());
|
||||||
|
const auto * precision_col_const = checkAndGetColumnConst<ColumnVector<UInt8>>(arguments[1].column.get());
|
||||||
|
|
||||||
|
auto result_col = ColumnString::create();
|
||||||
|
auto * result_col_string = assert_cast<ColumnString *>(result_col.get());
|
||||||
|
ColumnString::Chars & result_chars = result_col_string->getChars();
|
||||||
|
ColumnString::Offsets & result_offsets = result_col_string->getOffsets();
|
||||||
|
|
||||||
|
if constexpr (is_decimal<T>)
|
||||||
|
{
|
||||||
|
const auto * from_col = checkAndGetColumn<ColumnDecimal<T>>(arguments[0].column.get());
|
||||||
|
UInt8 from_scale = from_col->getScale();
|
||||||
|
|
||||||
|
if (from_col)
|
||||||
|
{
|
||||||
|
if (precision_col_const)
|
||||||
|
vectorConstant(from_col->getData(), precision_col_const->template getValue<UInt8>(), result_chars, result_offsets, from_scale);
|
||||||
|
else if (precision_col)
|
||||||
|
vectorVector(from_col->getData(), precision_col->getData(), result_chars, result_offsets, from_scale);
|
||||||
|
else
|
||||||
|
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of second argument of function formatDecimal", arguments[1].column->getName());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of first argument of function formatDecimal", arguments[0].column->getName());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto * from_col = checkAndGetColumn<ColumnVector<T>>(arguments[0].column.get());
|
||||||
|
if (from_col)
|
||||||
|
{
|
||||||
|
if (precision_col_const)
|
||||||
|
vectorConstant(from_col->getData(), precision_col_const->template getValue<UInt8>(), result_chars, result_offsets);
|
||||||
|
else if (precision_col)
|
||||||
|
vectorVector(from_col->getData(), precision_col->getData(), result_chars, result_offsets);
|
||||||
|
else
|
||||||
|
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of second argument of function formatDecimal", arguments[1].column->getName());
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of first argument of function formatDecimal", arguments[0].column->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result_col;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -1183,16 +1183,10 @@ public:
|
|||||||
|| (left_tuple && right_tuple && left_tuple->getElements().size() == right_tuple->getElements().size())
|
|| (left_tuple && right_tuple && left_tuple->getElements().size() == right_tuple->getElements().size())
|
||||||
|| (arguments[0]->equals(*arguments[1]))))
|
|| (arguments[0]->equals(*arguments[1]))))
|
||||||
{
|
{
|
||||||
try
|
if (!tryGetLeastSupertype(arguments))
|
||||||
{
|
|
||||||
getLeastSupertype(arguments);
|
|
||||||
}
|
|
||||||
catch (const Exception &)
|
|
||||||
{
|
|
||||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal types of arguments ({}, {})"
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal types of arguments ({}, {})"
|
||||||
" of function {}", arguments[0]->getName(), arguments[1]->getName(), getName());
|
" of function {}", arguments[0]->getName(), arguments[1]->getName(), getName());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (left_tuple && right_tuple)
|
if (left_tuple && right_tuple)
|
||||||
{
|
{
|
||||||
|
@ -293,7 +293,7 @@ struct SimHashImpl
|
|||||||
|
|
||||||
// we need to store the new word hash value to the oldest location.
|
// we need to store the new word hash value to the oldest location.
|
||||||
// for example, N = 5, array |a0|a1|a2|a3|a4|, now, a0 is the oldest location,
|
// for example, N = 5, array |a0|a1|a2|a3|a4|, now, a0 is the oldest location,
|
||||||
// so we need to store new word hash into location of a0, then ,this array become
|
// so we need to store new word hash into location of a0, then this array become
|
||||||
// |a5|a1|a2|a3|a4|, next time, a1 become the oldest location, we need to store new
|
// |a5|a1|a2|a3|a4|, next time, a1 become the oldest location, we need to store new
|
||||||
// word hash value into location of a1, then array become |a5|a6|a2|a3|a4|
|
// word hash value into location of a1, then array become |a5|a6|a2|a3|a4|
|
||||||
words[offset] = BytesRef{word_start, length};
|
words[offset] = BytesRef{word_start, length};
|
||||||
@ -793,4 +793,3 @@ REGISTER_FUNCTION(StringHash)
|
|||||||
factory.registerFunction<FunctionWordShingleMinHashArgCaseInsensitiveUTF8>();
|
factory.registerFunction<FunctionWordShingleMinHashArgCaseInsensitiveUTF8>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
376
src/Functions/GregorianDate.cpp
Normal file
376
src/Functions/GregorianDate.cpp
Normal file
@ -0,0 +1,376 @@
|
|||||||
|
#include <Functions/GregorianDate.h>
|
||||||
|
|
||||||
|
#include <Common/Exception.h>
|
||||||
|
#include <IO/ReadBuffer.h>
|
||||||
|
#include <IO/ReadHelpers.h>
|
||||||
|
#include <IO/WriteBufferFromString.h>
|
||||||
|
#include <IO/WriteHelpers.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace ErrorCodes
|
||||||
|
{
|
||||||
|
extern const int CANNOT_PARSE_INPUT_ASSERTION_FAILED;
|
||||||
|
extern const int CANNOT_PARSE_DATE;
|
||||||
|
extern const int CANNOT_FORMAT_DATETIME;
|
||||||
|
extern const int LOGICAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
inline constexpr bool is_leap_year(int32_t year)
|
||||||
|
{
|
||||||
|
return (year % 4 == 0) && ((year % 400 == 0) || (year % 100 != 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr uint8_t monthLength(bool is_leap_year, uint8_t month)
|
||||||
|
{
|
||||||
|
switch (month)
|
||||||
|
{
|
||||||
|
case 1: return 31;
|
||||||
|
case 2: return is_leap_year ? 29 : 28;
|
||||||
|
case 3: return 31;
|
||||||
|
case 4: return 30;
|
||||||
|
case 5: return 31;
|
||||||
|
case 6: return 30;
|
||||||
|
case 7: return 31;
|
||||||
|
case 8: return 31;
|
||||||
|
case 9: return 30;
|
||||||
|
case 10: return 31;
|
||||||
|
case 11: return 30;
|
||||||
|
case 12: return 31;
|
||||||
|
default:
|
||||||
|
std::terminate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Integer division truncated toward negative infinity.
|
||||||
|
*/
|
||||||
|
template <typename I, typename J>
|
||||||
|
inline constexpr I div(I x, J y)
|
||||||
|
{
|
||||||
|
const auto y_cast = static_cast<I>(y);
|
||||||
|
if (x > 0 && y_cast < 0)
|
||||||
|
return ((x - 1) / y_cast) - 1;
|
||||||
|
else if (x < 0 && y_cast > 0)
|
||||||
|
return ((x + 1) / y_cast) - 1;
|
||||||
|
else
|
||||||
|
return x / y_cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Integer modulus, satisfying div(x, y)*y + mod(x, y) == x.
|
||||||
|
*/
|
||||||
|
template <typename I, typename J>
|
||||||
|
inline constexpr I mod(I x, J y)
|
||||||
|
{
|
||||||
|
const auto y_cast = static_cast<I>(y);
|
||||||
|
const auto r = x % y_cast;
|
||||||
|
if ((x > 0 && y_cast < 0) || (x < 0 && y_cast > 0))
|
||||||
|
return r == 0 ? static_cast<I>(0) : r + y_cast;
|
||||||
|
else
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Like std::min(), but the type of operands may differ.
|
||||||
|
*/
|
||||||
|
template <typename I, typename J>
|
||||||
|
inline constexpr I min(I x, J y)
|
||||||
|
{
|
||||||
|
const auto y_cast = static_cast<I>(y);
|
||||||
|
return x < y_cast ? x : y_cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline char readDigit(ReadBuffer & in)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
if (!in.read(c))
|
||||||
|
throw Exception(ErrorCodes::CANNOT_PARSE_INPUT_ASSERTION_FAILED, "Cannot parse input: expected a digit at the end of stream");
|
||||||
|
else if (c < '0' || c > '9')
|
||||||
|
throw Exception(ErrorCodes::CANNOT_PARSE_INPUT_ASSERTION_FAILED, "Cannot read input: expected a digit but got something else");
|
||||||
|
else
|
||||||
|
return c - '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool tryReadDigit(ReadBuffer & in, char & c)
|
||||||
|
{
|
||||||
|
if (in.read(c) && c >= '0' && c <= '9')
|
||||||
|
{
|
||||||
|
c -= '0';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GregorianDate::init(ReadBuffer & in)
|
||||||
|
{
|
||||||
|
year_ = readDigit(in) * 1000
|
||||||
|
+ readDigit(in) * 100
|
||||||
|
+ readDigit(in) * 10
|
||||||
|
+ readDigit(in);
|
||||||
|
|
||||||
|
assertChar('-', in);
|
||||||
|
|
||||||
|
month_ = readDigit(in) * 10
|
||||||
|
+ readDigit(in);
|
||||||
|
|
||||||
|
assertChar('-', in);
|
||||||
|
|
||||||
|
day_of_month_ = readDigit(in) * 10
|
||||||
|
+ readDigit(in);
|
||||||
|
|
||||||
|
assertEOF(in);
|
||||||
|
|
||||||
|
if (month_ < 1 || month_ > 12 || day_of_month_ < 1 || day_of_month_ > monthLength(is_leap_year(year_), month_))
|
||||||
|
throw Exception(ErrorCodes::CANNOT_PARSE_DATE, "Invalid date, out of range (year: {}, month: {}, day_of_month: {}).");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GregorianDate::tryInit(ReadBuffer & in)
|
||||||
|
{
|
||||||
|
char c[8];
|
||||||
|
|
||||||
|
if ( !tryReadDigit(in, c[0])
|
||||||
|
|| !tryReadDigit(in, c[1])
|
||||||
|
|| !tryReadDigit(in, c[2])
|
||||||
|
|| !tryReadDigit(in, c[3])
|
||||||
|
|| !checkChar('-', in)
|
||||||
|
|| !tryReadDigit(in, c[4])
|
||||||
|
|| !tryReadDigit(in, c[5])
|
||||||
|
|| !checkChar('-', in)
|
||||||
|
|| !tryReadDigit(in, c[6])
|
||||||
|
|| !tryReadDigit(in, c[7])
|
||||||
|
|| !in.eof())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
year_ = c[0] * 1000 + c[1] * 100 + c[2] * 10 + c[3];
|
||||||
|
month_ = c[4] * 10 + c[5];
|
||||||
|
day_of_month_ = c[6] * 10 + c[7];
|
||||||
|
|
||||||
|
if (month_ < 1 || month_ > 12 || day_of_month_ < 1 || day_of_month_ > monthLength(is_leap_year(year_), month_))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GregorianDate::GregorianDate(ReadBuffer & in)
|
||||||
|
{
|
||||||
|
init(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GregorianDate::init(int64_t modified_julian_day)
|
||||||
|
{
|
||||||
|
const OrdinalDate ord(modified_julian_day);
|
||||||
|
const MonthDay md(is_leap_year(ord.year()), ord.dayOfYear());
|
||||||
|
|
||||||
|
year_ = ord.year();
|
||||||
|
month_ = md.month();
|
||||||
|
day_of_month_ = md.dayOfMonth();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GregorianDate::tryInit(int64_t modified_julian_day)
|
||||||
|
{
|
||||||
|
OrdinalDate ord;
|
||||||
|
if (!ord.tryInit(modified_julian_day))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MonthDay md(is_leap_year(ord.year()), ord.dayOfYear());
|
||||||
|
|
||||||
|
year_ = ord.year();
|
||||||
|
month_ = md.month();
|
||||||
|
day_of_month_ = md.dayOfMonth();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GregorianDate::GregorianDate(int64_t modified_julian_day)
|
||||||
|
{
|
||||||
|
init(modified_julian_day);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t GregorianDate::toModifiedJulianDay() const
|
||||||
|
{
|
||||||
|
const MonthDay md(month_, day_of_month_);
|
||||||
|
|
||||||
|
const auto day_of_year = md.dayOfYear(is_leap_year(year_));
|
||||||
|
|
||||||
|
const OrdinalDate ord(year_, day_of_year);
|
||||||
|
return ord.toModifiedJulianDay();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GregorianDate::tryToModifiedJulianDay(int64_t & res) const
|
||||||
|
{
|
||||||
|
const MonthDay md(month_, day_of_month_);
|
||||||
|
const auto day_of_year = md.dayOfYear(is_leap_year(year_));
|
||||||
|
OrdinalDate ord;
|
||||||
|
|
||||||
|
if (!ord.tryInit(year_, day_of_year))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
res = ord.toModifiedJulianDay();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ReturnType>
|
||||||
|
ReturnType GregorianDate::writeImpl(WriteBuffer & buf) const
|
||||||
|
{
|
||||||
|
if (year_ < 0 || year_ > 9999)
|
||||||
|
{
|
||||||
|
if constexpr (std::is_same_v<ReturnType, void>)
|
||||||
|
throw Exception(ErrorCodes::CANNOT_FORMAT_DATETIME,
|
||||||
|
"Impossible to stringify: year too big or small: {}", year_);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto y = year_;
|
||||||
|
writeChar('0' + y / 1000, buf); y %= 1000;
|
||||||
|
writeChar('0' + y / 100, buf); y %= 100;
|
||||||
|
writeChar('0' + y / 10, buf); y %= 10;
|
||||||
|
writeChar('0' + y , buf);
|
||||||
|
|
||||||
|
writeChar('-', buf);
|
||||||
|
|
||||||
|
auto m = month_;
|
||||||
|
writeChar('0' + m / 10, buf); m %= 10;
|
||||||
|
writeChar('0' + m , buf);
|
||||||
|
|
||||||
|
writeChar('-', buf);
|
||||||
|
|
||||||
|
auto d = day_of_month_;
|
||||||
|
writeChar('0' + d / 10, buf); d %= 10;
|
||||||
|
writeChar('0' + d , buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReturnType(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GregorianDate::toString() const
|
||||||
|
{
|
||||||
|
WriteBufferFromOwnString buf;
|
||||||
|
write(buf);
|
||||||
|
return buf.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrdinalDate::init(int32_t year, uint16_t day_of_year)
|
||||||
|
{
|
||||||
|
year_ = year;
|
||||||
|
day_of_year_ = day_of_year;
|
||||||
|
|
||||||
|
if (day_of_year < 1 || day_of_year > (is_leap_year(year) ? 366 : 365))
|
||||||
|
throw Exception(ErrorCodes::LOGICAL_ERROR, "Invalid ordinal date: {}-{}", year, day_of_year);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OrdinalDate::tryInit(int32_t year, uint16_t day_of_year)
|
||||||
|
{
|
||||||
|
year_ = year;
|
||||||
|
day_of_year_ = day_of_year;
|
||||||
|
|
||||||
|
return !(day_of_year < 1 || day_of_year > (is_leap_year(year) ? 366 : 365));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrdinalDate::init(int64_t modified_julian_day)
|
||||||
|
{
|
||||||
|
if (!tryInit(modified_julian_day))
|
||||||
|
throw Exception(
|
||||||
|
ErrorCodes::CANNOT_FORMAT_DATETIME,
|
||||||
|
"Value cannot be represented as date because it's out of range");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OrdinalDate::tryInit(int64_t modified_julian_day)
|
||||||
|
{
|
||||||
|
/// This function supports day number from -678941 to 2973119 (which represent 0000-01-01 and 9999-12-31 respectively).
|
||||||
|
|
||||||
|
if (modified_julian_day < -678941)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (modified_julian_day > 2973119)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto a = modified_julian_day + 678575;
|
||||||
|
const auto quad_cent = div(a, 146097);
|
||||||
|
const auto b = mod(a, 146097);
|
||||||
|
const auto cent = min(div(b, 36524), 3);
|
||||||
|
const auto c = b - cent * 36524;
|
||||||
|
const auto quad = div(c, 1461);
|
||||||
|
const auto d = mod(c, 1461);
|
||||||
|
const auto y = min(div(d, 365), 3);
|
||||||
|
|
||||||
|
day_of_year_ = d - y * 365 + 1;
|
||||||
|
year_ = static_cast<int32_t>(quad_cent * 400 + cent * 100 + quad * 4 + y + 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OrdinalDate::OrdinalDate(int32_t year, uint16_t day_of_year)
|
||||||
|
{
|
||||||
|
init(year, day_of_year);
|
||||||
|
}
|
||||||
|
|
||||||
|
OrdinalDate::OrdinalDate(int64_t modified_julian_day)
|
||||||
|
{
|
||||||
|
init(modified_julian_day);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t OrdinalDate::toModifiedJulianDay() const noexcept
|
||||||
|
{
|
||||||
|
const auto y = year_ - 1;
|
||||||
|
|
||||||
|
return day_of_year_
|
||||||
|
+ 365 * y
|
||||||
|
+ div(y, 4)
|
||||||
|
- div(y, 100)
|
||||||
|
+ div(y, 400)
|
||||||
|
- 678576;
|
||||||
|
}
|
||||||
|
|
||||||
|
MonthDay::MonthDay(uint8_t month, uint8_t day_of_month)
|
||||||
|
: month_(month)
|
||||||
|
, day_of_month_(day_of_month)
|
||||||
|
{
|
||||||
|
if (month < 1 || month > 12)
|
||||||
|
throw Exception(ErrorCodes::LOGICAL_ERROR, "Invalid month: {}", month);
|
||||||
|
/* We can't validate day_of_month here, because we don't know if
|
||||||
|
* it's a leap year. */
|
||||||
|
}
|
||||||
|
|
||||||
|
MonthDay::MonthDay(bool is_leap_year, uint16_t day_of_year)
|
||||||
|
{
|
||||||
|
if (day_of_year < 1 || day_of_year > (is_leap_year ? 366 : 365))
|
||||||
|
throw Exception(ErrorCodes::LOGICAL_ERROR, "Invalid day of year: {}{}",
|
||||||
|
(is_leap_year ? "leap, " : "non-leap, "), day_of_year);
|
||||||
|
|
||||||
|
month_ = 1;
|
||||||
|
uint16_t d = day_of_year;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const auto len = monthLength(is_leap_year, month_);
|
||||||
|
if (d <= len)
|
||||||
|
break;
|
||||||
|
++month_;
|
||||||
|
d -= len;
|
||||||
|
}
|
||||||
|
day_of_month_ = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t MonthDay::dayOfYear(bool is_leap_year) const
|
||||||
|
{
|
||||||
|
if (day_of_month_ < 1 || day_of_month_ > monthLength(is_leap_year, month_))
|
||||||
|
{
|
||||||
|
throw Exception(ErrorCodes::LOGICAL_ERROR, "Invalid day of month: {}{}-{}",
|
||||||
|
(is_leap_year ? "leap, " : "non-leap, "), month_, day_of_month_);
|
||||||
|
}
|
||||||
|
const auto k = month_ <= 2 ? 0 : is_leap_year ? -1 :-2;
|
||||||
|
return (367 * month_ - 362) / 12 + k + day_of_month_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template void GregorianDate::writeImpl<void>(WriteBuffer & buf) const;
|
||||||
|
template bool GregorianDate::writeImpl<bool>(WriteBuffer & buf) const;
|
||||||
|
|
||||||
|
}
|
@ -1,61 +1,61 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <base/extended_types.h>
|
|
||||||
#include <Common/Exception.h>
|
|
||||||
#include <Core/Types.h>
|
#include <Core/Types.h>
|
||||||
#include <IO/ReadBuffer.h>
|
|
||||||
#include <IO/ReadHelpers.h>
|
|
||||||
#include <IO/WriteBufferFromString.h>
|
|
||||||
#include <IO/WriteHelpers.h>
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
namespace ErrorCodes
|
|
||||||
{
|
|
||||||
extern const int CANNOT_PARSE_INPUT_ASSERTION_FAILED;
|
|
||||||
extern const int CANNOT_PARSE_DATE;
|
|
||||||
extern const int CANNOT_FORMAT_DATETIME;
|
|
||||||
extern const int LOGICAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Proleptic Gregorian calendar date. YearT is an integral type
|
class ReadBuffer;
|
||||||
* which should be at least 32 bits wide, and should preferably
|
class WriteBuffer;
|
||||||
* be signed.
|
|
||||||
*/
|
/// Proleptic Gregorian calendar date.
|
||||||
template <typename YearT = int32_t>
|
|
||||||
class GregorianDate
|
class GregorianDate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
GregorianDate() {}
|
||||||
|
|
||||||
|
void init(ReadBuffer & in);
|
||||||
|
bool tryInit(ReadBuffer & in);
|
||||||
|
|
||||||
/** Construct from date in text form 'YYYY-MM-DD' by reading from
|
/** Construct from date in text form 'YYYY-MM-DD' by reading from
|
||||||
* ReadBuffer.
|
* ReadBuffer.
|
||||||
*/
|
*/
|
||||||
explicit GregorianDate(ReadBuffer & in);
|
explicit GregorianDate(ReadBuffer & in);
|
||||||
|
|
||||||
|
void init(int64_t modified_julian_day);
|
||||||
|
bool tryInit(int64_t modified_julian_day);
|
||||||
|
|
||||||
/** Construct from Modified Julian Day. The type T is an
|
/** Construct from Modified Julian Day. The type T is an
|
||||||
* integral type which should be at least 32 bits wide, and
|
* integral type which should be at least 32 bits wide, and
|
||||||
* should preferably signed.
|
* should preferably signed.
|
||||||
*/
|
*/
|
||||||
explicit GregorianDate(is_integer auto modified_julian_day);
|
explicit GregorianDate(int64_t modified_julian_day);
|
||||||
|
|
||||||
/** Convert to Modified Julian Day. The type T is an integral type
|
/** Convert to Modified Julian Day. The type T is an integral type
|
||||||
* which should be at least 32 bits wide, and should preferably
|
* which should be at least 32 bits wide, and should preferably
|
||||||
* signed.
|
* signed.
|
||||||
*/
|
*/
|
||||||
template <is_integer T>
|
int64_t toModifiedJulianDay() const;
|
||||||
T toModifiedJulianDay() const;
|
bool tryToModifiedJulianDay(int64_t & res) const;
|
||||||
|
|
||||||
/** Write the date in text form 'YYYY-MM-DD' to a buffer.
|
/** Write the date in text form 'YYYY-MM-DD' to a buffer.
|
||||||
*/
|
*/
|
||||||
void write(WriteBuffer & buf) const;
|
void write(WriteBuffer & buf) const
|
||||||
|
{
|
||||||
|
writeImpl<void>(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tryWrite(WriteBuffer & buf) const
|
||||||
|
{
|
||||||
|
return writeImpl<bool>(buf);
|
||||||
|
}
|
||||||
|
|
||||||
/** Convert to a string in text form 'YYYY-MM-DD'.
|
/** Convert to a string in text form 'YYYY-MM-DD'.
|
||||||
*/
|
*/
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
|
|
||||||
YearT year() const noexcept
|
int32_t year() const noexcept
|
||||||
{
|
{
|
||||||
return year_;
|
return year_;
|
||||||
}
|
}
|
||||||
@ -65,41 +65,48 @@ namespace DB
|
|||||||
return month_;
|
return month_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t day_of_month() const noexcept /// NOLINT
|
uint8_t dayOfMonth() const noexcept
|
||||||
{
|
{
|
||||||
return day_of_month_;
|
return day_of_month_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
YearT year_; /// NOLINT
|
int32_t year_ = 0;
|
||||||
uint8_t month_; /// NOLINT
|
uint8_t month_ = 0;
|
||||||
uint8_t day_of_month_; /// NOLINT
|
uint8_t day_of_month_ = 0;
|
||||||
|
|
||||||
|
template <typename ReturnType>
|
||||||
|
ReturnType writeImpl(WriteBuffer & buf) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** ISO 8601 Ordinal Date. YearT is an integral type which should
|
/** ISO 8601 Ordinal Date.
|
||||||
* be at least 32 bits wide, and should preferably signed.
|
|
||||||
*/
|
*/
|
||||||
template <typename YearT = int32_t>
|
|
||||||
class OrdinalDate
|
class OrdinalDate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OrdinalDate(YearT year, uint16_t day_of_year);
|
OrdinalDate() {}
|
||||||
|
|
||||||
|
void init(int32_t year, uint16_t day_of_year);
|
||||||
|
bool tryInit(int32_t year, uint16_t day_of_year);
|
||||||
|
|
||||||
|
void init(int64_t modified_julian_day);
|
||||||
|
bool tryInit(int64_t modified_julian_day);
|
||||||
|
|
||||||
|
OrdinalDate(int32_t year, uint16_t day_of_year);
|
||||||
|
|
||||||
/** Construct from Modified Julian Day. The type T is an
|
/** Construct from Modified Julian Day. The type T is an
|
||||||
* integral type which should be at least 32 bits wide, and
|
* integral type which should be at least 32 bits wide, and
|
||||||
* should preferably signed.
|
* should preferably signed.
|
||||||
*/
|
*/
|
||||||
template <is_integer DayT>
|
explicit OrdinalDate(int64_t modified_julian_day);
|
||||||
explicit OrdinalDate(DayT modified_julian_day);
|
|
||||||
|
|
||||||
/** Convert to Modified Julian Day. The type T is an integral
|
/** Convert to Modified Julian Day. The type T is an integral
|
||||||
* type which should be at least 32 bits wide, and should
|
* type which should be at least 32 bits wide, and should
|
||||||
* preferably be signed.
|
* preferably be signed.
|
||||||
*/
|
*/
|
||||||
template <is_integer T>
|
int64_t toModifiedJulianDay() const noexcept;
|
||||||
T toModifiedJulianDay() const noexcept;
|
|
||||||
|
|
||||||
YearT year() const noexcept
|
int32_t year() const noexcept
|
||||||
{
|
{
|
||||||
return year_;
|
return year_;
|
||||||
}
|
}
|
||||||
@ -110,8 +117,8 @@ namespace DB
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
YearT year_; /// NOLINT
|
int32_t year_ = 0;
|
||||||
uint16_t day_of_year_; /// NOLINT
|
uint16_t day_of_year_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MonthDay
|
class MonthDay
|
||||||
@ -135,274 +142,14 @@ namespace DB
|
|||||||
return month_;
|
return month_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t day_of_month() const noexcept /// NOLINT
|
uint8_t dayOfMonth() const noexcept
|
||||||
{
|
{
|
||||||
return day_of_month_;
|
return day_of_month_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t month_; /// NOLINT
|
uint8_t month_ = 0;
|
||||||
uint8_t day_of_month_; /// NOLINT
|
uint8_t day_of_month_ = 0;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
/* Implementation */
|
|
||||||
|
|
||||||
namespace gd
|
|
||||||
{
|
|
||||||
using namespace DB;
|
|
||||||
|
|
||||||
template <typename YearT>
|
|
||||||
static inline constexpr bool is_leap_year(YearT year)
|
|
||||||
{
|
|
||||||
return (year % 4 == 0) && ((year % 400 == 0) || (year % 100 != 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline constexpr uint8_t monthLength(bool is_leap_year, uint8_t month)
|
|
||||||
{
|
|
||||||
switch (month)
|
|
||||||
{
|
|
||||||
case 1: return 31;
|
|
||||||
case 2: return is_leap_year ? 29 : 28;
|
|
||||||
case 3: return 31;
|
|
||||||
case 4: return 30;
|
|
||||||
case 5: return 31;
|
|
||||||
case 6: return 30;
|
|
||||||
case 7: return 31;
|
|
||||||
case 8: return 31;
|
|
||||||
case 9: return 30;
|
|
||||||
case 10: return 31;
|
|
||||||
case 11: return 30;
|
|
||||||
case 12: return 31;
|
|
||||||
default:
|
|
||||||
std::terminate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Integer division truncated toward negative infinity.
|
|
||||||
*/
|
|
||||||
template <typename I, typename J>
|
|
||||||
static inline constexpr I div(I x, J y)
|
|
||||||
{
|
|
||||||
const auto y_cast = static_cast<I>(y);
|
|
||||||
if (x > 0 && y_cast < 0)
|
|
||||||
return ((x - 1) / y_cast) - 1;
|
|
||||||
else if (x < 0 && y_cast > 0)
|
|
||||||
return ((x + 1) / y_cast) - 1;
|
|
||||||
else
|
|
||||||
return x / y_cast;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Integer modulus, satisfying div(x, y)*y + mod(x, y) == x.
|
|
||||||
*/
|
|
||||||
template <typename I, typename J>
|
|
||||||
static inline constexpr I mod(I x, J y)
|
|
||||||
{
|
|
||||||
const auto y_cast = static_cast<I>(y);
|
|
||||||
const auto r = x % y_cast;
|
|
||||||
if ((x > 0 && y_cast < 0) || (x < 0 && y_cast > 0))
|
|
||||||
return r == 0 ? static_cast<I>(0) : r + y_cast;
|
|
||||||
else
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Like std::min(), but the type of operands may differ.
|
|
||||||
*/
|
|
||||||
template <typename I, typename J>
|
|
||||||
static inline constexpr I min(I x, J y)
|
|
||||||
{
|
|
||||||
const auto y_cast = static_cast<I>(y);
|
|
||||||
return x < y_cast ? x : y_cast;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline char readDigit(ReadBuffer & in)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
if (!in.read(c))
|
|
||||||
throw Exception(ErrorCodes::CANNOT_PARSE_INPUT_ASSERTION_FAILED, "Cannot parse input: expected a digit at the end of stream");
|
|
||||||
else if (c < '0' || c > '9')
|
|
||||||
throw Exception(ErrorCodes::CANNOT_PARSE_INPUT_ASSERTION_FAILED, "Cannot read input: expected a digit but got something else");
|
|
||||||
else
|
|
||||||
return c - '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace DB
|
|
||||||
{
|
|
||||||
template <typename YearT>
|
|
||||||
GregorianDate<YearT>::GregorianDate(ReadBuffer & in)
|
|
||||||
{
|
|
||||||
year_ = gd::readDigit(in) * 1000
|
|
||||||
+ gd::readDigit(in) * 100
|
|
||||||
+ gd::readDigit(in) * 10
|
|
||||||
+ gd::readDigit(in);
|
|
||||||
|
|
||||||
assertChar('-', in);
|
|
||||||
|
|
||||||
month_ = gd::readDigit(in) * 10
|
|
||||||
+ gd::readDigit(in);
|
|
||||||
|
|
||||||
assertChar('-', in);
|
|
||||||
|
|
||||||
day_of_month_ = gd::readDigit(in) * 10
|
|
||||||
+ gd::readDigit(in);
|
|
||||||
|
|
||||||
assertEOF(in);
|
|
||||||
|
|
||||||
if (month_ < 1 || month_ > 12 || day_of_month_ < 1 || day_of_month_ > gd::monthLength(gd::is_leap_year(year_), month_))
|
|
||||||
throw Exception(ErrorCodes::CANNOT_PARSE_DATE, "Invalid date: {}", toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename YearT>
|
|
||||||
GregorianDate<YearT>::GregorianDate(is_integer auto modified_julian_day)
|
|
||||||
{
|
|
||||||
const OrdinalDate<YearT> ord(modified_julian_day);
|
|
||||||
const MonthDay md(gd::is_leap_year(ord.year()), ord.dayOfYear());
|
|
||||||
year_ = ord.year();
|
|
||||||
month_ = md.month();
|
|
||||||
day_of_month_ = md.day_of_month();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename YearT>
|
|
||||||
template <is_integer T>
|
|
||||||
T GregorianDate<YearT>::toModifiedJulianDay() const
|
|
||||||
{
|
|
||||||
const MonthDay md(month_, day_of_month_);
|
|
||||||
const auto day_of_year = md.dayOfYear(gd::is_leap_year(year_));
|
|
||||||
const OrdinalDate<YearT> ord(year_, day_of_year);
|
|
||||||
return ord.template toModifiedJulianDay<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename YearT>
|
|
||||||
void GregorianDate<YearT>::write(WriteBuffer & buf) const
|
|
||||||
{
|
|
||||||
if (year_ < 0 || year_ > 9999)
|
|
||||||
{
|
|
||||||
throw Exception(ErrorCodes::CANNOT_FORMAT_DATETIME,
|
|
||||||
"Impossible to stringify: year too big or small: {}", DB::toString(year_));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto y = year_;
|
|
||||||
writeChar('0' + y / 1000, buf); y %= 1000;
|
|
||||||
writeChar('0' + y / 100, buf); y %= 100;
|
|
||||||
writeChar('0' + y / 10, buf); y %= 10;
|
|
||||||
writeChar('0' + y , buf);
|
|
||||||
|
|
||||||
writeChar('-', buf);
|
|
||||||
|
|
||||||
auto m = month_;
|
|
||||||
writeChar('0' + m / 10, buf); m %= 10;
|
|
||||||
writeChar('0' + m , buf);
|
|
||||||
|
|
||||||
writeChar('-', buf);
|
|
||||||
|
|
||||||
auto d = day_of_month_;
|
|
||||||
writeChar('0' + d / 10, buf); d %= 10;
|
|
||||||
writeChar('0' + d , buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename YearT>
|
|
||||||
std::string GregorianDate<YearT>::toString() const
|
|
||||||
{
|
|
||||||
WriteBufferFromOwnString buf;
|
|
||||||
write(buf);
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename YearT>
|
|
||||||
OrdinalDate<YearT>::OrdinalDate(YearT year, uint16_t day_of_year)
|
|
||||||
: year_(year)
|
|
||||||
, day_of_year_(day_of_year)
|
|
||||||
{
|
|
||||||
if (day_of_year < 1 || day_of_year > (gd::is_leap_year(year) ? 366 : 365))
|
|
||||||
{
|
|
||||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Invalid ordinal date: {}-{}", toString(year), toString(day_of_year));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename YearT>
|
|
||||||
template <is_integer DayT>
|
|
||||||
OrdinalDate<YearT>::OrdinalDate(DayT modified_julian_day)
|
|
||||||
{
|
|
||||||
/// This function supports day number from -678941 to 2973119 (which represent 0000-01-01 and 9999-12-31 respectively).
|
|
||||||
|
|
||||||
if constexpr (is_signed_v<DayT> && std::numeric_limits<DayT>::lowest() < -678941)
|
|
||||||
if (modified_julian_day < -678941)
|
|
||||||
throw Exception(
|
|
||||||
ErrorCodes::CANNOT_FORMAT_DATETIME,
|
|
||||||
"Value cannot be represented as date because it's out of range");
|
|
||||||
|
|
||||||
if constexpr (std::numeric_limits<DayT>::max() > 2973119)
|
|
||||||
if (modified_julian_day > 2973119)
|
|
||||||
throw Exception(
|
|
||||||
ErrorCodes::CANNOT_FORMAT_DATETIME,
|
|
||||||
"Value cannot be represented as date because it's out of range");
|
|
||||||
|
|
||||||
const auto a = modified_julian_day + 678575;
|
|
||||||
const auto quad_cent = gd::div(a, 146097);
|
|
||||||
const auto b = gd::mod(a, 146097);
|
|
||||||
const auto cent = gd::min(gd::div(b, 36524), 3);
|
|
||||||
const auto c = b - cent * 36524;
|
|
||||||
const auto quad = gd::div(c, 1461);
|
|
||||||
const auto d = gd::mod(c, 1461);
|
|
||||||
const auto y = gd::min(gd::div(d, 365), 3);
|
|
||||||
|
|
||||||
day_of_year_ = d - y * 365 + 1;
|
|
||||||
year_ = static_cast<YearT>(quad_cent * 400 + cent * 100 + quad * 4 + y + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename YearT>
|
|
||||||
template <is_integer T>
|
|
||||||
T OrdinalDate<YearT>::toModifiedJulianDay() const noexcept
|
|
||||||
{
|
|
||||||
const auto y = year_ - 1;
|
|
||||||
return day_of_year_
|
|
||||||
+ 365 * y
|
|
||||||
+ gd::div(y, 4)
|
|
||||||
- gd::div(y, 100)
|
|
||||||
+ gd::div(y, 400)
|
|
||||||
- 678576;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline MonthDay::MonthDay(uint8_t month, uint8_t day_of_month)
|
|
||||||
: month_(month)
|
|
||||||
, day_of_month_(day_of_month)
|
|
||||||
{
|
|
||||||
if (month < 1 || month > 12)
|
|
||||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Invalid month: {}", DB::toString(month));
|
|
||||||
/* We can't validate day_of_month here, because we don't know if
|
|
||||||
* it's a leap year. */
|
|
||||||
}
|
|
||||||
|
|
||||||
inline MonthDay::MonthDay(bool is_leap_year, uint16_t day_of_year)
|
|
||||||
{
|
|
||||||
if (day_of_year < 1 || day_of_year > (is_leap_year ? 366 : 365))
|
|
||||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Invalid day of year: {}{}",
|
|
||||||
(is_leap_year ? "leap, " : "non-leap, "), DB::toString(day_of_year));
|
|
||||||
|
|
||||||
month_ = 1;
|
|
||||||
uint16_t d = day_of_year;
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
const auto len = gd::monthLength(is_leap_year, month_);
|
|
||||||
if (d <= len)
|
|
||||||
break;
|
|
||||||
month_++;
|
|
||||||
d -= len;
|
|
||||||
}
|
|
||||||
day_of_month_ = d;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint16_t MonthDay::dayOfYear(bool is_leap_year) const
|
|
||||||
{
|
|
||||||
if (day_of_month_ < 1 || day_of_month_ > gd::monthLength(is_leap_year, month_))
|
|
||||||
{
|
|
||||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Invalid day of month: {}{}-{}",
|
|
||||||
(is_leap_year ? "leap, " : "non-leap, "), DB::toString(month_), DB::toString(day_of_month_));
|
|
||||||
}
|
|
||||||
const auto k = month_ <= 2 ? 0 : is_leap_year ? -1 :-2;
|
|
||||||
return (367 * month_ - 362) / 12 + k + day_of_month_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,8 @@ public:
|
|||||||
REGISTER_FUNCTION(CurrentDatabase)
|
REGISTER_FUNCTION(CurrentDatabase)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionCurrentDatabase>();
|
factory.registerFunction<FunctionCurrentDatabase>();
|
||||||
factory.registerAlias("DATABASE", "currentDatabase", FunctionFactory::CaseInsensitive);
|
factory.registerAlias("DATABASE", FunctionCurrentDatabase::name, FunctionFactory::CaseInsensitive);
|
||||||
|
factory.registerAlias("current_database", FunctionCurrentDatabase::name, FunctionFactory::CaseInsensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
88
src/Functions/currentSchemas.cpp
Normal file
88
src/Functions/currentSchemas.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#include <Functions/IFunction.h>
|
||||||
|
#include <Functions/FunctionFactory.h>
|
||||||
|
#include <Interpreters/Context.h>
|
||||||
|
#include <DataTypes/DataTypeArray.h>
|
||||||
|
#include <DataTypes/DataTypeString.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace ErrorCodes
|
||||||
|
{
|
||||||
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
class FunctionCurrentSchemas : public IFunction
|
||||||
|
{
|
||||||
|
const String db_name;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr auto name = "currentSchemas";
|
||||||
|
static FunctionPtr create(ContextPtr context)
|
||||||
|
{
|
||||||
|
return std::make_shared<FunctionCurrentSchemas>(context->getCurrentDatabase());
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit FunctionCurrentSchemas(const String & db_name_) :
|
||||||
|
db_name{db_name_}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
String getName() const override
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getNumberOfArguments() const override
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
|
||||||
|
{
|
||||||
|
// For compatibility, function implements the same signature as Postgres'
|
||||||
|
const bool argument_is_valid = arguments.size() == 1 && isBool(arguments.front());
|
||||||
|
if (!argument_is_valid)
|
||||||
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Argument for function {} must be bool", getName());
|
||||||
|
|
||||||
|
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDeterministic() const override { return false; }
|
||||||
|
|
||||||
|
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
|
||||||
|
|
||||||
|
ColumnPtr executeImpl(const ColumnsWithTypeAndName &, const DataTypePtr &, size_t input_rows_count) const override
|
||||||
|
{
|
||||||
|
return DataTypeArray(std::make_shared<DataTypeString>())
|
||||||
|
.createColumnConst(input_rows_count, Array { db_name });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_FUNCTION(CurrentSchema)
|
||||||
|
{
|
||||||
|
factory.registerFunction<FunctionCurrentSchemas>(FunctionDocumentation
|
||||||
|
{
|
||||||
|
.description=R"(
|
||||||
|
Returns a single-element array with the name of the current database
|
||||||
|
|
||||||
|
Requires a boolean parameter, but it is ignored actually. It is required just for compatibility with the implementation of this function in other DB engines.
|
||||||
|
|
||||||
|
[example:common]
|
||||||
|
)",
|
||||||
|
.examples{
|
||||||
|
{"common", "SELECT current_schemas(true);", "['default']"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
FunctionFactory::CaseInsensitive);
|
||||||
|
factory.registerAlias("current_schemas", FunctionCurrentSchemas::name, FunctionFactory::CaseInsensitive);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -13,12 +13,12 @@
|
|||||||
#include <IO/WriteBufferFromVector.h>
|
#include <IO/WriteBufferFromVector.h>
|
||||||
#include <IO/WriteHelpers.h>
|
#include <IO/WriteHelpers.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace ErrorCodes
|
namespace ErrorCodes
|
||||||
{
|
{
|
||||||
extern const int CANNOT_FORMAT_DATETIME;
|
|
||||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,25 +56,14 @@ namespace DB
|
|||||||
{
|
{
|
||||||
if constexpr (nullOnErrors)
|
if constexpr (nullOnErrors)
|
||||||
{
|
{
|
||||||
try
|
GregorianDate gd;
|
||||||
{
|
(*vec_null_map_to)[i] = !(gd.tryInit(vec_from[i]) && gd.tryWrite(write_buffer));
|
||||||
const GregorianDate<> gd(vec_from[i]);
|
|
||||||
gd.write(write_buffer);
|
|
||||||
(*vec_null_map_to)[i] = false;
|
|
||||||
}
|
|
||||||
catch (const Exception & e)
|
|
||||||
{
|
|
||||||
if (e.code() == ErrorCodes::CANNOT_FORMAT_DATETIME)
|
|
||||||
(*vec_null_map_to)[i] = true;
|
|
||||||
else
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
writeChar(0, write_buffer);
|
writeChar(0, write_buffer);
|
||||||
offsets_to[i] = write_buffer.count();
|
offsets_to[i] = write_buffer.count();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const GregorianDate<> gd(vec_from[i]);
|
GregorianDate gd(vec_from[i]);
|
||||||
gd.write(write_buffer);
|
gd.write(write_buffer);
|
||||||
writeChar(0, write_buffer);
|
writeChar(0, write_buffer);
|
||||||
offsets_to[i] = write_buffer.count();
|
offsets_to[i] = write_buffer.count();
|
||||||
|
@ -65,15 +65,7 @@ private:
|
|||||||
if (!arg_string)
|
if (!arg_string)
|
||||||
return argument.type;
|
return argument.type;
|
||||||
|
|
||||||
try
|
return DataTypeFactory::instance().get(arg_string->getDataAt(0).toString());
|
||||||
{
|
|
||||||
DataTypePtr type = DataTypeFactory::instance().get(arg_string->getDataAt(0).toString());
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
catch (const DB::Exception &)
|
|
||||||
{
|
|
||||||
return argument.type;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ namespace
|
|||||||
static Int32 daysSinceEpochFromDayOfYear(Int32 year_, Int32 day_of_year_)
|
static Int32 daysSinceEpochFromDayOfYear(Int32 year_, Int32 day_of_year_)
|
||||||
{
|
{
|
||||||
if (!isDayOfYearValid(year_, day_of_year_))
|
if (!isDayOfYearValid(year_, day_of_year_))
|
||||||
throw Exception(ErrorCodes::CANNOT_PARSE_DATETIME, "Invalid day of year, year:{} day of year:{}", year_, day_of_year_);
|
throw Exception(ErrorCodes::CANNOT_PARSE_DATETIME, "Invalid day of year, out of range (year: {} day of year: {})", year_, day_of_year_);
|
||||||
|
|
||||||
Int32 res = daysSinceEpochFromDate(year_, 1, 1);
|
Int32 res = daysSinceEpochFromDate(year_, 1, 1);
|
||||||
res += day_of_year_ - 1;
|
res += day_of_year_ - 1;
|
||||||
@ -408,7 +408,7 @@ namespace
|
|||||||
static Int32 daysSinceEpochFromDate(Int32 year_, Int32 month_, Int32 day_)
|
static Int32 daysSinceEpochFromDate(Int32 year_, Int32 month_, Int32 day_)
|
||||||
{
|
{
|
||||||
if (!isDateValid(year_, month_, day_))
|
if (!isDateValid(year_, month_, day_))
|
||||||
throw Exception(ErrorCodes::CANNOT_PARSE_DATETIME, "Invalid date, year:{} month:{} day:{}", year_, month_, day_);
|
throw Exception(ErrorCodes::CANNOT_PARSE_DATETIME, "Invalid date, out of range (year: {} month: {} day_of_month: {})", year_, month_, day_);
|
||||||
|
|
||||||
Int32 res = cumulativeYearDays[year_ - 1970];
|
Int32 res = cumulativeYearDays[year_ - 1970];
|
||||||
res += isLeapYear(year_) ? cumulativeLeapDays[month_ - 1] : cumulativeDays[month_ - 1];
|
res += isLeapYear(year_) ? cumulativeLeapDays[month_ - 1] : cumulativeDays[month_ - 1];
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
#include <Common/assert_cast.h>
|
#include <Common/assert_cast.h>
|
||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
#include <IO/WriteHelpers.h>
|
#include <IO/WriteHelpers.h>
|
||||||
#include <Interpreters/Context_fwd.h>
|
#include <Interpreters/Context.h>
|
||||||
|
|
||||||
|
|
||||||
namespace ProfileEvents
|
namespace ProfileEvents
|
||||||
{
|
{
|
||||||
@ -40,11 +41,17 @@ enum class FunctionSleepVariant
|
|||||||
template <FunctionSleepVariant variant>
|
template <FunctionSleepVariant variant>
|
||||||
class FunctionSleep : public IFunction
|
class FunctionSleep : public IFunction
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
UInt64 max_microseconds;
|
||||||
public:
|
public:
|
||||||
static constexpr auto name = variant == FunctionSleepVariant::PerBlock ? "sleep" : "sleepEachRow";
|
static constexpr auto name = variant == FunctionSleepVariant::PerBlock ? "sleep" : "sleepEachRow";
|
||||||
static FunctionPtr create(ContextPtr)
|
static FunctionPtr create(ContextPtr context)
|
||||||
|
{
|
||||||
|
return std::make_shared<FunctionSleep<variant>>(context->getSettingsRef().function_sleep_max_microseconds_per_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionSleep(UInt64 max_microseconds_) : max_microseconds(max_microseconds_)
|
||||||
{
|
{
|
||||||
return std::make_shared<FunctionSleep<variant>>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the name of the function.
|
/// Get the name of the function.
|
||||||
@ -105,13 +112,19 @@ public:
|
|||||||
if (size > 0)
|
if (size > 0)
|
||||||
{
|
{
|
||||||
/// When sleeping, the query cannot be cancelled. For ability to cancel query, we limit sleep time.
|
/// When sleeping, the query cannot be cancelled. For ability to cancel query, we limit sleep time.
|
||||||
if (seconds > 3.0) /// The choice is arbitrary
|
if (max_microseconds && seconds * 1e6 > max_microseconds)
|
||||||
throw Exception(ErrorCodes::TOO_SLOW, "The maximum sleep time is 3 seconds. Requested: {}", toString(seconds));
|
throw Exception(ErrorCodes::TOO_SLOW, "The maximum sleep time is {} microseconds. Requested: {}", max_microseconds, seconds);
|
||||||
|
|
||||||
if (!dry_run)
|
if (!dry_run)
|
||||||
{
|
{
|
||||||
UInt64 count = (variant == FunctionSleepVariant::PerBlock ? 1 : size);
|
UInt64 count = (variant == FunctionSleepVariant::PerBlock ? 1 : size);
|
||||||
UInt64 microseconds = static_cast<UInt64>(seconds * count * 1e6);
|
UInt64 microseconds = static_cast<UInt64>(seconds * count * 1e6);
|
||||||
|
|
||||||
|
if (max_microseconds && microseconds > max_microseconds)
|
||||||
|
throw Exception(ErrorCodes::TOO_SLOW,
|
||||||
|
"The maximum sleep time is {} microseconds. Requested: {} microseconds per block (of size {})",
|
||||||
|
max_microseconds, microseconds, size);
|
||||||
|
|
||||||
sleepForMicroseconds(microseconds);
|
sleepForMicroseconds(microseconds);
|
||||||
ProfileEvents::increment(ProfileEvents::SleepFunctionCalls, count);
|
ProfileEvents::increment(ProfileEvents::SleepFunctionCalls, count);
|
||||||
ProfileEvents::increment(ProfileEvents::SleepFunctionMicroseconds, microseconds);
|
ProfileEvents::increment(ProfileEvents::SleepFunctionMicroseconds, microseconds);
|
||||||
|
302
src/Functions/substringIndex.cpp
Normal file
302
src/Functions/substringIndex.cpp
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
#include <Columns/ColumnConst.h>
|
||||||
|
#include <Columns/ColumnString.h>
|
||||||
|
#include <DataTypes/DataTypeString.h>
|
||||||
|
#include <Functions/FunctionFactory.h>
|
||||||
|
#include <Functions/FunctionHelpers.h>
|
||||||
|
#include <Functions/IFunction.h>
|
||||||
|
#include <Functions/PositionImpl.h>
|
||||||
|
#include <Interpreters/Context_fwd.h>
|
||||||
|
#include <base/find_symbols.h>
|
||||||
|
#include <Common/UTF8Helpers.h>
|
||||||
|
#include <Common/register_objects.h>
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace ErrorCodes
|
||||||
|
{
|
||||||
|
extern const int ILLEGAL_COLUMN;
|
||||||
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||||
|
extern const int BAD_ARGUMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
template <bool is_utf8>
|
||||||
|
class FunctionSubstringIndex : public IFunction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr auto name = is_utf8 ? "substringIndexUTF8" : "substringIndex";
|
||||||
|
|
||||||
|
|
||||||
|
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionSubstringIndex>(); }
|
||||||
|
|
||||||
|
String getName() const override { return name; }
|
||||||
|
|
||||||
|
size_t getNumberOfArguments() const override { return 3; }
|
||||||
|
|
||||||
|
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return true; }
|
||||||
|
|
||||||
|
bool useDefaultImplementationForConstants() const override { return true; }
|
||||||
|
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; }
|
||||||
|
|
||||||
|
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
|
||||||
|
{
|
||||||
|
if (!isString(arguments[0]))
|
||||||
|
throw Exception(
|
||||||
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||||
|
"Illegal type {} of first argument of function {}, String expected",
|
||||||
|
arguments[0]->getName(),
|
||||||
|
getName());
|
||||||
|
|
||||||
|
if (!isString(arguments[1]))
|
||||||
|
throw Exception(
|
||||||
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||||
|
"Illegal type {} of second argument of function {}, String expected",
|
||||||
|
arguments[1]->getName(),
|
||||||
|
getName());
|
||||||
|
|
||||||
|
if (!isNativeInteger(arguments[2]))
|
||||||
|
throw Exception(
|
||||||
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||||
|
"Illegal type {} of third argument of function {}, Integer expected",
|
||||||
|
arguments[2]->getName(),
|
||||||
|
getName());
|
||||||
|
|
||||||
|
return std::make_shared<DataTypeString>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
|
||||||
|
{
|
||||||
|
ColumnPtr column_string = arguments[0].column;
|
||||||
|
ColumnPtr column_delim = arguments[1].column;
|
||||||
|
ColumnPtr column_count = arguments[2].column;
|
||||||
|
|
||||||
|
const ColumnConst * column_delim_const = checkAndGetColumnConst<ColumnString>(column_delim.get());
|
||||||
|
if (!column_delim_const)
|
||||||
|
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Second argument to {} must be a constant String", getName());
|
||||||
|
|
||||||
|
String delim = column_delim_const->getValue<String>();
|
||||||
|
if constexpr (!is_utf8)
|
||||||
|
{
|
||||||
|
if (delim.size() != 1)
|
||||||
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Second argument to {} must be a single character", getName());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (UTF8::countCodePoints(reinterpret_cast<const UInt8 *>(delim.data()), delim.size()) != 1)
|
||||||
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Second argument to {} must be a single UTF-8 character", getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto column_res = ColumnString::create();
|
||||||
|
ColumnString::Chars & vec_res = column_res->getChars();
|
||||||
|
ColumnString::Offsets & offsets_res = column_res->getOffsets();
|
||||||
|
|
||||||
|
const ColumnConst * column_string_const = checkAndGetColumnConst<ColumnString>(column_string.get());
|
||||||
|
if (column_string_const)
|
||||||
|
{
|
||||||
|
String str = column_string_const->getValue<String>();
|
||||||
|
constantVector(str, delim, column_count.get(), vec_res, offsets_res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto * col_str = checkAndGetColumn<ColumnString>(column_string.get());
|
||||||
|
if (!col_str)
|
||||||
|
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "First argument to {} must be a String", getName());
|
||||||
|
|
||||||
|
bool is_count_const = isColumnConst(*column_count);
|
||||||
|
if (is_count_const)
|
||||||
|
{
|
||||||
|
Int64 count = column_count->getInt(0);
|
||||||
|
vectorConstant(col_str, delim, count, vec_res, offsets_res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vectorVector(col_str, delim, column_count.get(), vec_res, offsets_res);
|
||||||
|
}
|
||||||
|
return column_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void vectorVector(
|
||||||
|
const ColumnString * str_column,
|
||||||
|
const String & delim,
|
||||||
|
const IColumn * count_column,
|
||||||
|
ColumnString::Chars & res_data,
|
||||||
|
ColumnString::Offsets & res_offsets)
|
||||||
|
{
|
||||||
|
size_t rows = str_column->size();
|
||||||
|
res_data.reserve(str_column->getChars().size() / 2);
|
||||||
|
res_offsets.reserve(rows);
|
||||||
|
|
||||||
|
std::unique_ptr<PositionCaseSensitiveUTF8::SearcherInBigHaystack> searcher
|
||||||
|
= !is_utf8 ? nullptr : std::make_unique<PositionCaseSensitiveUTF8::SearcherInBigHaystack>(delim.data(), delim.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < rows; ++i)
|
||||||
|
{
|
||||||
|
StringRef str_ref = str_column->getDataAt(i);
|
||||||
|
Int64 count = count_column->getInt(i);
|
||||||
|
|
||||||
|
StringRef res_ref;
|
||||||
|
if constexpr (!is_utf8)
|
||||||
|
res_ref = substringIndex(str_ref, delim[0], count);
|
||||||
|
else
|
||||||
|
res_ref = substringIndexUTF8(searcher.get(), str_ref, delim, count);
|
||||||
|
|
||||||
|
appendToResultColumn(res_ref, res_data, res_offsets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vectorConstant(
|
||||||
|
const ColumnString * str_column,
|
||||||
|
const String & delim,
|
||||||
|
Int64 count,
|
||||||
|
ColumnString::Chars & res_data,
|
||||||
|
ColumnString::Offsets & res_offsets)
|
||||||
|
{
|
||||||
|
size_t rows = str_column->size();
|
||||||
|
res_data.reserve(str_column->getChars().size() / 2);
|
||||||
|
res_offsets.reserve(rows);
|
||||||
|
|
||||||
|
std::unique_ptr<PositionCaseSensitiveUTF8::SearcherInBigHaystack> searcher
|
||||||
|
= !is_utf8 ? nullptr : std::make_unique<PositionCaseSensitiveUTF8::SearcherInBigHaystack>(delim.data(), delim.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < rows; ++i)
|
||||||
|
{
|
||||||
|
StringRef str_ref = str_column->getDataAt(i);
|
||||||
|
|
||||||
|
StringRef res_ref;
|
||||||
|
if constexpr (!is_utf8)
|
||||||
|
res_ref = substringIndex(str_ref, delim[0], count);
|
||||||
|
else
|
||||||
|
res_ref = substringIndexUTF8(searcher.get(), str_ref, delim, count);
|
||||||
|
|
||||||
|
appendToResultColumn(res_ref, res_data, res_offsets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void constantVector(
|
||||||
|
const String & str,
|
||||||
|
const String & delim,
|
||||||
|
const IColumn * count_column,
|
||||||
|
ColumnString::Chars & res_data,
|
||||||
|
ColumnString::Offsets & res_offsets)
|
||||||
|
{
|
||||||
|
size_t rows = count_column->size();
|
||||||
|
res_data.reserve(str.size() * rows / 2);
|
||||||
|
res_offsets.reserve(rows);
|
||||||
|
|
||||||
|
std::unique_ptr<PositionCaseSensitiveUTF8::SearcherInBigHaystack> searcher
|
||||||
|
= !is_utf8 ? nullptr : std::make_unique<PositionCaseSensitiveUTF8::SearcherInBigHaystack>(delim.data(), delim.size());
|
||||||
|
|
||||||
|
StringRef str_ref{str.data(), str.size()};
|
||||||
|
for (size_t i = 0; i < rows; ++i)
|
||||||
|
{
|
||||||
|
Int64 count = count_column->getInt(i);
|
||||||
|
|
||||||
|
StringRef res_ref;
|
||||||
|
if constexpr (!is_utf8)
|
||||||
|
res_ref = substringIndex(str_ref, delim[0], count);
|
||||||
|
else
|
||||||
|
res_ref = substringIndexUTF8(searcher.get(), str_ref, delim, count);
|
||||||
|
|
||||||
|
appendToResultColumn(res_ref, res_data, res_offsets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void appendToResultColumn(const StringRef & res_ref, ColumnString::Chars & res_data, ColumnString::Offsets & res_offsets)
|
||||||
|
{
|
||||||
|
size_t res_offset = res_data.size();
|
||||||
|
res_data.resize(res_offset + res_ref.size + 1);
|
||||||
|
memcpy(&res_data[res_offset], res_ref.data, res_ref.size);
|
||||||
|
res_offset += res_ref.size;
|
||||||
|
res_data[res_offset] = 0;
|
||||||
|
++res_offset;
|
||||||
|
|
||||||
|
res_offsets.emplace_back(res_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static StringRef substringIndexUTF8(
|
||||||
|
const PositionCaseSensitiveUTF8::SearcherInBigHaystack * searcher, const StringRef & str_ref, const String & delim, Int64 count)
|
||||||
|
{
|
||||||
|
if (count == 0)
|
||||||
|
return {str_ref.data, 0};
|
||||||
|
|
||||||
|
const auto * begin = reinterpret_cast<const UInt8 *>(str_ref.data);
|
||||||
|
const auto * end = reinterpret_cast<const UInt8 *>(str_ref.data + str_ref.size);
|
||||||
|
const auto * pos = begin;
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
Int64 i = 0;
|
||||||
|
while (i < count)
|
||||||
|
{
|
||||||
|
pos = searcher->search(pos, end - pos);
|
||||||
|
|
||||||
|
if (pos != end)
|
||||||
|
{
|
||||||
|
pos += delim.size();
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return str_ref;
|
||||||
|
}
|
||||||
|
return {begin, static_cast<size_t>(pos - begin - delim.size())};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Int64 total = 0;
|
||||||
|
while (pos < end && end != (pos = searcher->search(pos, end - pos)))
|
||||||
|
{
|
||||||
|
pos += delim.size();
|
||||||
|
++total;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total + count < 0)
|
||||||
|
return str_ref;
|
||||||
|
|
||||||
|
pos = begin;
|
||||||
|
Int64 i = 0;
|
||||||
|
Int64 count_from_left = total + 1 + count;
|
||||||
|
while (i < count_from_left && pos < end && end != (pos = searcher->search(pos, end - pos)))
|
||||||
|
{
|
||||||
|
pos += delim.size();
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return {pos, static_cast<size_t>(end - pos)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static StringRef substringIndex(const StringRef & str_ref, char delim, Int64 count)
|
||||||
|
{
|
||||||
|
if (count == 0)
|
||||||
|
return {str_ref.data, 0};
|
||||||
|
|
||||||
|
const auto * pos = count > 0 ? str_ref.data : str_ref.data + str_ref.size - 1;
|
||||||
|
const auto * end = count > 0 ? str_ref.data + str_ref.size : str_ref.data - 1;
|
||||||
|
int d = count > 0 ? 1 : -1;
|
||||||
|
|
||||||
|
for (; count; pos += d)
|
||||||
|
{
|
||||||
|
if (pos == end)
|
||||||
|
return str_ref;
|
||||||
|
if (*pos == delim)
|
||||||
|
count -= d;
|
||||||
|
}
|
||||||
|
pos -= d;
|
||||||
|
return {
|
||||||
|
d > 0 ? str_ref.data : pos + 1, static_cast<size_t>(d > 0 ? pos - str_ref.data : str_ref.data + str_ref.size - pos - 1)};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
REGISTER_FUNCTION(SubstringIndex)
|
||||||
|
{
|
||||||
|
factory.registerFunction<FunctionSubstringIndex<false>>(); /// substringIndex
|
||||||
|
factory.registerFunction<FunctionSubstringIndex<true>>(); /// substringIndexUTF8
|
||||||
|
|
||||||
|
factory.registerAlias("SUBSTRING_INDEX", "substringIndex", FunctionFactory::CaseInsensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -17,8 +17,6 @@ namespace DB
|
|||||||
{
|
{
|
||||||
extern const int ILLEGAL_COLUMN;
|
extern const int ILLEGAL_COLUMN;
|
||||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||||
extern const int CANNOT_PARSE_INPUT_ASSERTION_FAILED;
|
|
||||||
extern const int CANNOT_PARSE_DATE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Name, typename ToDataType, bool nullOnErrors>
|
template <typename Name, typename ToDataType, bool nullOnErrors>
|
||||||
@ -78,27 +76,18 @@ namespace DB
|
|||||||
|
|
||||||
if constexpr (nullOnErrors)
|
if constexpr (nullOnErrors)
|
||||||
{
|
{
|
||||||
try
|
GregorianDate date;
|
||||||
{
|
|
||||||
const GregorianDate<> date(read_buffer);
|
int64_t res = 0;
|
||||||
vec_to[i] = date.toModifiedJulianDay<typename ToDataType::FieldType>();
|
bool success = date.tryInit(read_buffer) && date.tryToModifiedJulianDay(res);
|
||||||
vec_null_map_to[i] = false;
|
|
||||||
}
|
vec_to[i] = static_cast<typename ToDataType::FieldType>(res);
|
||||||
catch (const Exception & e)
|
vec_null_map_to[i] = !success;
|
||||||
{
|
|
||||||
if (e.code() == ErrorCodes::CANNOT_PARSE_INPUT_ASSERTION_FAILED || e.code() == ErrorCodes::CANNOT_PARSE_DATE)
|
|
||||||
{
|
|
||||||
vec_to[i] = static_cast<Int32>(0);
|
|
||||||
vec_null_map_to[i] = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const GregorianDate<> date(read_buffer);
|
const GregorianDate date(read_buffer);
|
||||||
vec_to[i] = date.toModifiedJulianDay<typename ToDataType::FieldType>();
|
vec_to[i] = static_cast<typename ToDataType::FieldType>(date.toModifiedJulianDay());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ namespace
|
|||||||
{
|
{
|
||||||
initialize(arguments, result_type);
|
initialize(arguments, result_type);
|
||||||
|
|
||||||
const auto * in = arguments.front().column.get();
|
const auto * in = arguments[0].column.get();
|
||||||
|
|
||||||
if (isColumnConst(*in))
|
if (isColumnConst(*in))
|
||||||
return executeConst(arguments, result_type, input_rows_count);
|
return executeConst(arguments, result_type, input_rows_count);
|
||||||
@ -165,6 +165,10 @@ namespace
|
|||||||
if (!cache.default_column && arguments.size() == 4)
|
if (!cache.default_column && arguments.size() == 4)
|
||||||
default_non_const = castColumn(arguments[3], result_type);
|
default_non_const = castColumn(arguments[3], result_type);
|
||||||
|
|
||||||
|
ColumnPtr in_casted = arguments[0].column;
|
||||||
|
if (arguments.size() == 3)
|
||||||
|
in_casted = castColumn(arguments[0], result_type);
|
||||||
|
|
||||||
auto column_result = result_type->createColumn();
|
auto column_result = result_type->createColumn();
|
||||||
if (cache.is_empty)
|
if (cache.is_empty)
|
||||||
{
|
{
|
||||||
@ -174,30 +178,30 @@ namespace
|
|||||||
}
|
}
|
||||||
else if (cache.table_num_to_idx)
|
else if (cache.table_num_to_idx)
|
||||||
{
|
{
|
||||||
if (!executeNum<ColumnVector<UInt8>>(in, *column_result, default_non_const)
|
if (!executeNum<ColumnVector<UInt8>>(in, *column_result, default_non_const, *in_casted)
|
||||||
&& !executeNum<ColumnVector<UInt16>>(in, *column_result, default_non_const)
|
&& !executeNum<ColumnVector<UInt16>>(in, *column_result, default_non_const, *in_casted)
|
||||||
&& !executeNum<ColumnVector<UInt32>>(in, *column_result, default_non_const)
|
&& !executeNum<ColumnVector<UInt32>>(in, *column_result, default_non_const, *in_casted)
|
||||||
&& !executeNum<ColumnVector<UInt64>>(in, *column_result, default_non_const)
|
&& !executeNum<ColumnVector<UInt64>>(in, *column_result, default_non_const, *in_casted)
|
||||||
&& !executeNum<ColumnVector<Int8>>(in, *column_result, default_non_const)
|
&& !executeNum<ColumnVector<Int8>>(in, *column_result, default_non_const, *in_casted)
|
||||||
&& !executeNum<ColumnVector<Int16>>(in, *column_result, default_non_const)
|
&& !executeNum<ColumnVector<Int16>>(in, *column_result, default_non_const, *in_casted)
|
||||||
&& !executeNum<ColumnVector<Int32>>(in, *column_result, default_non_const)
|
&& !executeNum<ColumnVector<Int32>>(in, *column_result, default_non_const, *in_casted)
|
||||||
&& !executeNum<ColumnVector<Int64>>(in, *column_result, default_non_const)
|
&& !executeNum<ColumnVector<Int64>>(in, *column_result, default_non_const, *in_casted)
|
||||||
&& !executeNum<ColumnVector<Float32>>(in, *column_result, default_non_const)
|
&& !executeNum<ColumnVector<Float32>>(in, *column_result, default_non_const, *in_casted)
|
||||||
&& !executeNum<ColumnVector<Float64>>(in, *column_result, default_non_const)
|
&& !executeNum<ColumnVector<Float64>>(in, *column_result, default_non_const, *in_casted)
|
||||||
&& !executeNum<ColumnDecimal<Decimal32>>(in, *column_result, default_non_const)
|
&& !executeNum<ColumnDecimal<Decimal32>>(in, *column_result, default_non_const, *in_casted)
|
||||||
&& !executeNum<ColumnDecimal<Decimal64>>(in, *column_result, default_non_const))
|
&& !executeNum<ColumnDecimal<Decimal64>>(in, *column_result, default_non_const, *in_casted))
|
||||||
{
|
{
|
||||||
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of first argument of function {}", in->getName(), getName());
|
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of first argument of function {}", in->getName(), getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cache.table_string_to_idx)
|
else if (cache.table_string_to_idx)
|
||||||
{
|
{
|
||||||
if (!executeString(in, *column_result, default_non_const))
|
if (!executeString(in, *column_result, default_non_const, *in_casted))
|
||||||
executeContiguous(in, *column_result, default_non_const);
|
executeContiguous(in, *column_result, default_non_const, *in_casted);
|
||||||
}
|
}
|
||||||
else if (cache.table_anything_to_idx)
|
else if (cache.table_anything_to_idx)
|
||||||
{
|
{
|
||||||
executeAnything(in, *column_result, default_non_const);
|
executeAnything(in, *column_result, default_non_const, *in_casted);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "State of the function `transform` is not initialized");
|
throw Exception(ErrorCodes::LOGICAL_ERROR, "State of the function `transform` is not initialized");
|
||||||
@ -218,7 +222,7 @@ namespace
|
|||||||
return impl->execute(args, result_type, input_rows_count);
|
return impl->execute(args, result_type, input_rows_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void executeAnything(const IColumn * in, IColumn & column_result, const ColumnPtr default_non_const) const
|
void executeAnything(const IColumn * in, IColumn & column_result, const ColumnPtr default_non_const, const IColumn & in_casted) const
|
||||||
{
|
{
|
||||||
const size_t size = in->size();
|
const size_t size = in->size();
|
||||||
const auto & table = *cache.table_anything_to_idx;
|
const auto & table = *cache.table_anything_to_idx;
|
||||||
@ -236,11 +240,11 @@ namespace
|
|||||||
else if (default_non_const)
|
else if (default_non_const)
|
||||||
column_result.insertFrom(*default_non_const, i);
|
column_result.insertFrom(*default_non_const, i);
|
||||||
else
|
else
|
||||||
column_result.insertFrom(*in, i);
|
column_result.insertFrom(in_casted, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void executeContiguous(const IColumn * in, IColumn & column_result, const ColumnPtr default_non_const) const
|
void executeContiguous(const IColumn * in, IColumn & column_result, const ColumnPtr default_non_const, const IColumn & in_casted) const
|
||||||
{
|
{
|
||||||
const size_t size = in->size();
|
const size_t size = in->size();
|
||||||
const auto & table = *cache.table_string_to_idx;
|
const auto & table = *cache.table_string_to_idx;
|
||||||
@ -255,12 +259,12 @@ namespace
|
|||||||
else if (default_non_const)
|
else if (default_non_const)
|
||||||
column_result.insertFrom(*default_non_const, i);
|
column_result.insertFrom(*default_non_const, i);
|
||||||
else
|
else
|
||||||
column_result.insertFrom(*in, i);
|
column_result.insertFrom(in_casted, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool executeNum(const IColumn * in_untyped, IColumn & column_result, const ColumnPtr default_non_const) const
|
bool executeNum(const IColumn * in_untyped, IColumn & column_result, const ColumnPtr default_non_const, const IColumn & in_casted) const
|
||||||
{
|
{
|
||||||
const auto * const in = checkAndGetColumn<T>(in_untyped);
|
const auto * const in = checkAndGetColumn<T>(in_untyped);
|
||||||
if (!in)
|
if (!in)
|
||||||
@ -297,7 +301,7 @@ namespace
|
|||||||
else if (default_non_const)
|
else if (default_non_const)
|
||||||
column_result.insertFrom(*default_non_const, i);
|
column_result.insertFrom(*default_non_const, i);
|
||||||
else
|
else
|
||||||
column_result.insertFrom(*in, i);
|
column_result.insertFrom(in_casted, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -451,7 +455,7 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool executeString(const IColumn * in_untyped, IColumn & column_result, const ColumnPtr default_non_const) const
|
bool executeString(const IColumn * in_untyped, IColumn & column_result, const ColumnPtr default_non_const, const IColumn & in_casted) const
|
||||||
{
|
{
|
||||||
const auto * const in = checkAndGetColumn<ColumnString>(in_untyped);
|
const auto * const in = checkAndGetColumn<ColumnString>(in_untyped);
|
||||||
if (!in)
|
if (!in)
|
||||||
@ -488,7 +492,7 @@ namespace
|
|||||||
else if (default_non_const)
|
else if (default_non_const)
|
||||||
column_result.insertFrom(*default_non_const, 0);
|
column_result.insertFrom(*default_non_const, 0);
|
||||||
else
|
else
|
||||||
column_result.insertFrom(*in, i);
|
column_result.insertFrom(in_casted, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -654,13 +658,13 @@ namespace
|
|||||||
std::unique_ptr<StringToIdx> table_string_to_idx;
|
std::unique_ptr<StringToIdx> table_string_to_idx;
|
||||||
std::unique_ptr<AnythingToIdx> table_anything_to_idx;
|
std::unique_ptr<AnythingToIdx> table_anything_to_idx;
|
||||||
|
|
||||||
bool is_empty = false;
|
|
||||||
|
|
||||||
ColumnPtr from_column;
|
ColumnPtr from_column;
|
||||||
ColumnPtr to_column;
|
ColumnPtr to_column;
|
||||||
ColumnPtr default_column;
|
ColumnPtr default_column;
|
||||||
|
|
||||||
std::atomic<bool> initialized{false};
|
bool is_empty = false;
|
||||||
|
bool initialized = false;
|
||||||
|
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -693,13 +697,12 @@ namespace
|
|||||||
/// Can be called from different threads. It works only on the first call.
|
/// Can be called from different threads. It works only on the first call.
|
||||||
void initialize(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type) const
|
void initialize(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type) const
|
||||||
{
|
{
|
||||||
|
std::lock_guard lock(cache.mutex);
|
||||||
if (cache.initialized)
|
if (cache.initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const DataTypePtr & from_type = arguments[0].type;
|
const DataTypePtr & from_type = arguments[0].type;
|
||||||
|
|
||||||
std::lock_guard lock(cache.mutex);
|
|
||||||
|
|
||||||
if (from_type->onlyNull())
|
if (from_type->onlyNull())
|
||||||
{
|
{
|
||||||
cache.is_empty = true;
|
cache.is_empty = true;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include <Columns/ColumnTuple.h>
|
#include <Columns/ColumnTuple.h>
|
||||||
#include <Columns/ColumnVector.h>
|
|
||||||
#include <DataTypes/DataTypeTuple.h>
|
#include <DataTypes/DataTypeTuple.h>
|
||||||
#include <DataTypes/DataTypesNumber.h>
|
#include <DataTypes/DataTypesNumber.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
@ -86,7 +85,7 @@ public:
|
|||||||
auto plus_elem = plus->build({left_type, right_type});
|
auto plus_elem = plus->build({left_type, right_type});
|
||||||
res_type = plus_elem->getResultType();
|
res_type = plus_elem->getResultType();
|
||||||
}
|
}
|
||||||
catch (DB::Exception & e)
|
catch (Exception & e)
|
||||||
{
|
{
|
||||||
e.addMessage("While executing function {} for tuple element {}", getName(), i);
|
e.addMessage("While executing function {} for tuple element {}", getName(), i);
|
||||||
throw;
|
throw;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user