diff --git a/.gitignore b/.gitignore
index 8d1a188befb..6c0865d1959 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,8 @@
/docs/tools/venv/
/docs/en/development/build/
/docs/ru/development/build/
+/docs/en/single.md
+/docs/ru/single.md
# callgrind files
callgrind.out.*
@@ -176,7 +178,6 @@ utils/zookeeper-create-entry-to-download-part/zookeeper-create-entry-to-download
utils/zookeeper-dump-tree/zookeeper-dump-tree
utils/zookeeper-remove-by-list/zookeeper-remove-by-list
dbms/src/Storages/tests/remove_symlink_directory
-dbms/tests/queries/1_stateful
debian/control
debian/copyright
debian/tmp/
@@ -239,5 +240,6 @@ node_modules
public
website/docs
website/presentations
+website/package-lock.json
.DS_Store
*/.DS_Store
diff --git a/.gitmodules b/.gitmodules
index 1f392b73c83..742e4616276 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -37,3 +37,12 @@
[submodule "contrib/llvm"]
path = contrib/llvm
url = https://github.com/ClickHouse-Extras/llvm
+[submodule "contrib/mariadb-connector-c"]
+ path = contrib/mariadb-connector-c
+ url = https://github.com/MariaDB/mariadb-connector-c.git
+[submodule "contrib/jemalloc"]
+ path = contrib/jemalloc
+ url = https://github.com/jemalloc/jemalloc.git
+[submodule "contrib/unixodbc"]
+ path = contrib/unixodbc
+ url = https://github.com/ClickHouse-Extras/UnixODBC.git
diff --git a/.travis.yml b/.travis.yml
index 705b6977114..d658b8d285c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,26 +3,6 @@ language: generic
matrix:
fast_finish: true
include:
-# - os: linux
-#
-# cache:
-# ccache: true
-# timeout: 1000
-#
-# addons:
-# apt:
-# update: true
-# sources:
-# - ubuntu-toolchain-r-test
-# packages: [ g++-7, libicu-dev, libreadline-dev, libmysqlclient-dev, unixodbc-dev, libltdl-dev, libssl-dev, libboost-dev, zlib1g-dev, libdouble-conversion-dev, libsparsehash-dev, librdkafka-dev, libcapnp-dev, libsparsehash-dev, libgoogle-perftools-dev, bash, expect, python, python-lxml, python-termcolor, curl, perl, sudo, openssl ]
-#
-# env:
-# - MATRIX_EVAL="export CC=gcc-7 && export CXX=g++-7"
-#
-# script:
-# - env TEST_RUN= utils/travis/normal.sh
-
-
# We need to have gcc7 headers to compile c++17 code on clang
- os: linux
@@ -41,33 +21,11 @@ matrix:
packages: [ ninja-build, g++-7, clang-5.0, lld-5.0, libicu-dev, libreadline-dev, libmysqlclient-dev, unixodbc-dev, libltdl-dev, libssl-dev, libboost-dev, zlib1g-dev, libdouble-conversion-dev, libsparsehash-dev, librdkafka-dev, libcapnp-dev, libsparsehash-dev, libgoogle-perftools-dev, bash, expect, python, python-lxml, python-termcolor, curl, perl, sudo, openssl]
env:
- - MATRIX_EVAL="export CC=clang-5.0 && export CXX=clang++-5.0"
+ - MATRIX_EVAL="export CC=clang-5.0 CXX=clang++-5.0"
script:
- utils/travis/normal.sh
-
-# TODO: fix internal compiler
-# - os: linux
-#
-# sudo: required
-#
-# cache:
-# timeout: 1000
-# directories:
-# - /var/cache/pbuilder/ccache
-#
-# addons:
-# apt:
-# packages: [ pbuilder, fakeroot, debhelper ]
-#
-# env:
-# - MATRIX_EVAL="export DEB_CC=clang-5.0 && export DEB_CXX=clang++-5.0"
-#
-# script:
-# - utils/travis/pbuilder.sh
-
-
- os: linux
sudo: required
@@ -85,69 +43,6 @@ matrix:
script:
- utils/travis/pbuilder.sh
-
-# - os: linux
-#
-# sudo: required
-#
-# cache:
-# timeout: 1000
-# directories:
-# - /var/cache/pbuilder/ccache
-#
-# addons:
-# apt:
-# update: true
-# packages: [ pbuilder, fakeroot, debhelper ]
-#
-# env:
-# - MATRIX_EVAL="export ARCH=i386"
-#
-# script:
-# - env PBUILDER_TIMEOUT=40m TEST_TRUE=true TEST_RUN= utils/travis/pbuilder.sh
-
-
-# TODO: Can't bootstrap bionic on trusty host
-# - os: linux
-#
-# sudo: required
-#
-# cache:
-# timeout: 1000
-# directories:
-# - /var/cache/pbuilder/ccache
-#
-# addons:
-# apt:
-# update: true
-# packages: [ pbuilder, fakeroot, debhelper ]
-#
-# env:
-# - MATRIX_EVAL="export DEB_CC=clang-6.0 && export DEB_CXX=clang++-6.0 && export DIST=bionic && export EXTRAPACKAGES='clang-6.0 lld-6.0'"
-#
-# script:
-# - utils/travis/pbuilder.sh
-
-
-# Cant fit to time limit (48min)
-# - os: osx
-# osx_image: xcode9.2
-#
-# cache:
-# ccache: true
-# timeout: 1000
-#
-# before_install:
-# - brew install unixodbc gcc ccache libtool gettext zlib readline double-conversion gperftools google-sparsehash lz4 zstd || true
-# - brew link --overwrite gcc || true
-#
-# env:
-# - MATRIX_EVAL="export CC=gcc-8 && export CXX=g++-8"
-#
-# script:
-# - env CMAKE_FLAGS="-DUSE_INTERNAL_BOOST_LIBRARY=1" utils/travis/normal.sh
-
-
allow_failures:
- os: osx
diff --git a/CHANGELOG.draft.md b/CHANGELOG.draft.md
index 5ed63c620ba..93c681b0336 100644
--- a/CHANGELOG.draft.md
+++ b/CHANGELOG.draft.md
@@ -1,15 +1 @@
-## en:
-
-### Improvements:
-* Added Nullable support for runningDifference function. [#2590](https://github.com/yandex/ClickHouse/issues/2590)
-
-### Bug fiexs:
-* Fixed switching to default databases in case of client reconnection. [#2580](https://github.com/yandex/ClickHouse/issues/2580)
-
-## ru:
-
-### Улучшения:
-* Добавлена поддержка Nullable для функции runningDifference. [#2590](https://github.com/yandex/ClickHouse/issues/2590)
-
-### Исправление ошибок:
-* Исправлено переключение на дефолтную базу данных при переподключении клиента. [#2580](https://github.com/yandex/ClickHouse/issues/2580)
+## RU
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cde357611d4..4f26f565e8e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,122 @@
+## ClickHouse release 18.5.1, 2018-07-31
+
+### New features:
+
+* Added the hash function `murmurHash2_32` [#2756](https://github.com/yandex/ClickHouse/pull/2756).
+
+### Improvements:
+
+* Now you can use the `from_env` attribute to set values in config files from environment variables [#2741](https://github.com/yandex/ClickHouse/pull/2741).
+* Added case-insensitive versions of the `coalesce`, `ifNull`, and `nullIf functions` [#2752](https://github.com/yandex/ClickHouse/pull/2752).
+
+### Bug fixes:
+
+* Fixed a possible bug when starting a replica [#2759](https://github.com/yandex/ClickHouse/pull/2759).
+
+## ClickHouse release 18.4.0, 2018-07-28
+
+### New features:
+
+* Added system tables: `formats`, `data_type_families`, `aggregate_function_combinators`, `table_functions`, `table_engines`, `collations` [#2721](https://github.com/yandex/ClickHouse/pull/2721).
+* Added the ability to use a table function instead of a table as an argument of a `remote` or `cluster` table function [#2708](https://github.com/yandex/ClickHouse/pull/2708).
+* Support for `HTTP Basic` authentication in the replication protocol [#2727](https://github.com/yandex/ClickHouse/pull/2727).
+* The `has` function now allows searching for a numeric value in an array of `Enum` values [Maxim Khrisanfov](https://github.com/yandex/ClickHouse/pull/2699).
+* Support for adding arbitrary message separators when reading from `Kafka` [Amos Bird](https://github.com/yandex/ClickHouse/pull/2701).
+
+### Improvements:
+
+* The `ALTER TABLE t DELETE WHERE` query does not rewrite data chunks that were not affected by the WHERE condition [#2694](https://github.com/yandex/ClickHouse/pull/2694).
+* The `use_minimalistic_checksums_in_zookeeper` option for `ReplicatedMergeTree` tables is enabled by default. This setting was added in version 1.1.54378, 2018-04-16. Versions that are older than 1.1.54378 can no longer be installed.
+* Support for running `KILL` and `OPTIMIZE` queries that specify `ON CLUSTER` [Winter Zhang](https://github.com/yandex/ClickHouse/pull/2689).
+
+### Bug fixes:
+
+* Fixed the error `Column ... is not under an aggregate function and not in GROUP BY` for aggregation with an IN expression. This bug appeared in version 18.1.0. ([bbdd780b](https://github.com/yandex/ClickHouse/commit/bbdd780be0be06a0f336775941cdd536878dd2c2))
+* Fixed a bug in the `windowFunnel` aggregate function [Winter Zhang](https://github.com/yandex/ClickHouse/pull/2735).
+* Fixed a bug in the `anyHeavy` aggregate function ([a2101df2](https://github.com/yandex/ClickHouse/commit/a2101df25a6a0fba99aa71f8793d762af2b801ee))
+* Fixed server crash when using the `countArray()` aggregate function.
+
+## ClickHouse release 18.1.0, 2018-07-23
+
+### New features:
+
+* Support for the `ALTER TABLE t DELETE WHERE` query for non-replicated MergeTree tables ([#2634](https://github.com/yandex/ClickHouse/pull/2634)).
+* Support for arbitrary types for the `uniq*` family of aggregate functions ([#2010](https://github.com/yandex/ClickHouse/issues/2010)).
+* Support for arbitrary types in comparison operators ([#2026](https://github.com/yandex/ClickHouse/issues/2026)).
+* The `users.xml` file allows setting a subnet mask in the format `10.0.0.1/255.255.255.0`. This is necessary for using masks for IPv6 networks with zeros in the middle ([#2637](https://github.com/yandex/ClickHouse/pull/2637)).
+* Added the `arrayDistinct` function ([#2670](https://github.com/yandex/ClickHouse/pull/2670)).
+* The SummingMergeTree engine can now work with AggregateFunction type columns ([Constantin S. Pan](https://github.com/yandex/ClickHouse/pull/2566)).
+
+### Improvements:
+
+* Changed the numbering scheme for release versions. Now the first part contains the year of release (A.D., Moscow timezone, minus 2000), the second part contains the number for major changes (increases for most releases), and the third part is the patch version. Releases are still backwards compatible, unless otherwise stated in the changelog.
+* Faster conversions of floating-point numbers to a string ([Amos Bird](https://github.com/yandex/ClickHouse/pull/2664)).
+* If some rows were skipped during an insert due to parsing errors (this is possible with the `input_allow_errors_num` and `input_allow_errors_ratio` settings enabled), the number of skipped rows is now written to the server log ([Leonardo Cecchi](https://github.com/yandex/ClickHouse/pull/2669)).
+
+### Bug fixes:
+
+* Fixed the TRUNCATE command for temporary tables ([Amos Bird](https://github.com/yandex/ClickHouse/pull/2624)).
+* Fixed a rare deadlock in the ZooKeeper client library that occurred when there was a network error while reading the response ([c315200](https://github.com/yandex/ClickHouse/commit/c315200e64b87e44bdf740707fc857d1fdf7e947)).
+* Fixed an error during a CAST to Nullable types ([#1322](https://github.com/yandex/ClickHouse/issues/1322)).
+* Fixed the incorrect result of the `maxIntersection()` function when the boundaries of intervals coincided ([Michael Furmur](https://github.com/yandex/ClickHouse/pull/2657)).
+* Fixed incorrect transformation of the OR expression chain in a function argument ([chenxing-xc](https://github.com/yandex/ClickHouse/pull/2663)).
+* Fixed performance degradation for queries containing `IN (subquery)` expressions inside another subquery ([#2571](https://github.com/yandex/ClickHouse/issues/2571)).
+* Fixed incompatibility between servers with different versions in distributed queries that use a `CAST` function that isn't in uppercase letters ([fe8c4d6](https://github.com/yandex/ClickHouse/commit/fe8c4d64e434cacd4ceef34faa9005129f2190a5)).
+* Added missing quoting of identifiers for queries to an external DBMS ([#2635](https://github.com/yandex/ClickHouse/issues/2635)).
+
+### Backward incompatible changes:
+
+* Converting a string containing the number zero to DateTime does not work. Example: `SELECT toDateTime('0')`. This is also the reason that `DateTime DEFAULT '0'` does not work in tables, as well as `0` in dictionaries. Solution: replace `0` with `0000-00-00 00:00:00`.
+
+
+## ClickHouse release 1.1.54394, 2018-07-12
+
+### New features:
+
+* Added the `histogram` aggregate function ([Mikhail Surin](https://github.com/yandex/ClickHouse/pull/2521)).
+* Now `OPTIMIZE TABLE ... FINAL` can be used without specifying partitions for `ReplicatedMergeTree` ([Amos Bird](https://github.com/yandex/ClickHouse/pull/2600)).
+
+### Bug fixes:
+
+* Fixed a problem with a very small timeout for sockets (one second) for reading and writing when sending and downloading replicated data, which made it impossible to download larger parts if there is a load on the network or disk (it resulted in cyclical attempts to download parts). This error occurred in version 1.1.54388.
+* Fixed issues when using chroot in ZooKeeper if you inserted duplicate data blocks in the table.
+* The `has` function now works correctly for an array with Nullable elements ([#2115](https://github.com/yandex/ClickHouse/issues/2115)).
+* The `system.tables` table now works correctly when used in distributed queries. The `metadata_modification_time` and `engine_full` columns are now non-virtual. Fixed an error that occurred if only these columns were requested from the table.
+* Fixed how an empty `TinyLog` table works after inserting an empty data block ([#2563](https://github.com/yandex/ClickHouse/issues/2563)).
+* The `system.zookeeper` table works if the value of the node in ZooKeeper is NULL.
+
+## ClickHouse release 1.1.54390, 2018-07-06
+
+### New features:
+
+* Queries can be sent in `multipart/form-data` format (in the `query` field), which is useful if external data is also sent for query processing ([Olga Hvostikova](https://github.com/yandex/ClickHouse/pull/2490)).
+* Added the ability to enable or disable processing single or double quotes when reading data in CSV format. You can configure this in the `format_csv_allow_single_quotes` and `format_csv_allow_double_quotes` settings ([Amos Bird](https://github.com/yandex/ClickHouse/pull/2574)).
+* Now `OPTIMIZE TABLE ... FINAL` can be used without specifying the partition for non-replicated variants of `MergeTree` ([Amos Bird](https://github.com/yandex/ClickHouse/pull/2599)).
+
+### Improvements:
+
+* Improved performance, reduced memory consumption, and correct tracking of memory consumption with use of the IN operator when a table index could be used ([#2584](https://github.com/yandex/ClickHouse/pull/2584)).
+* Removed redundant checking of checksums when adding a data part. This is important when there are a large number of replicas, because in these cases the total number of checks was equal to N^2.
+* Added support for `Array(Tuple(...))` arguments for the `arrayEnumerateUniq` function ([#2573](https://github.com/yandex/ClickHouse/pull/2573)).
+* Added `Nullable` support for the `runningDifference` function ([#2594](https://github.com/yandex/ClickHouse/pull/2594)).
+* Improved query analysis performance when there is a very large number of expressions ([#2572](https://github.com/yandex/ClickHouse/pull/2572)).
+* Faster selection of data parts for merging in `ReplicatedMergeTree` tables. Faster recovery of the ZooKeeper session ([#2597](https://github.com/yandex/ClickHouse/pull/2597)).
+* The `format_version.txt` file for `MergeTree` tables is re-created if it is missing, which makes sense if ClickHouse is launched after copying the directory structure without files ([Ciprian Hacman](https://github.com/yandex/ClickHouse/pull/2593)).
+
+### Bug fixes:
+
+* Fixed a bug when working with ZooKeeper that could make it impossible to recover the session and readonly states of tables before restarting the server.
+* Fixed a bug when working with ZooKeeper that could result in old nodes not being deleted if the session is interrupted.
+* Fixed an error in the `quantileTDigest` function for Float arguments (this bug was introduced in version 1.1.54388) ([Mikhail Surin](https://github.com/yandex/ClickHouse/pull/2553)).
+* Fixed a bug in the index for MergeTree tables if the primary key column is located inside the function for converting types between signed and unsigned integers of the same size ([#2603](https://github.com/yandex/ClickHouse/pull/2603)).
+* Fixed segfault if `macros` are used but they aren't in the config file ([#2570](https://github.com/yandex/ClickHouse/pull/2570)).
+* Fixed switching to the default database when reconnecting the client ([#2583](https://github.com/yandex/ClickHouse/pull/2583)).
+* Fixed a bug that occurred when the `use_index_for_in_with_subqueries` setting was disabled.
+
+### Security fix:
+
+* Sending files is no longer possible when connected to MySQL (`LOAD DATA LOCAL INFILE`).
+
## ClickHouse release 1.1.54388, 2018-06-28
### New features:
diff --git a/CHANGELOG_RU.md b/CHANGELOG_RU.md
index 5282e10a556..494f76379c2 100644
--- a/CHANGELOG_RU.md
+++ b/CHANGELOG_RU.md
@@ -1,3 +1,78 @@
+## ClickHouse release 18.6.0, 2018-08-02
+
+### Новые возможности:
+* Добавлена поддержка ON выражений для JOIN ON синтаксиса:
+`JOIN ON Expr([table.]column, ...) = Expr([table.]column, ...) [AND Expr([table.]column, ...) = Expr([table.]column, ...) ...]`
+Выражение должно представлять из себя цепочку равенств, объединенных оператором AND. Каждая часть равенства может являться произвольным выражением над столбцами одной из таблиц. Поддержана возможность использования fully qualified имен столбцов (`table.name`, `database.table.name`, `table_alias.name`, `subquery_alias.name`) для правой таблицы. [#2742](https://github.com/yandex/ClickHouse/pull/2742)
+* Добавлена возможность включить HTTPS для репликации. [#2760](https://github.com/yandex/ClickHouse/pull/2760)
+
+### Улучшения:
+* Сервер передаёт на клиент также patch-компонент своей версии. Данные о patch компоненте версии добавлены в `system.processes` и `query_log`. [#2646](https://github.com/yandex/ClickHouse/pull/2646)
+
+
+## ClickHouse release 18.5.1, 2018-07-31
+
+### Новые возможности:
+* Добавлена функция хеширования `murmurHash2_32` [#2756](https://github.com/yandex/ClickHouse/pull/2756).
+
+### Улучшения:
+* Добавлена возможность указывать значения в конфигурационных файлах из переменных окружения с помощью атрибута `from_env` [#2741](https://github.com/yandex/ClickHouse/pull/2741).
+* Добавлены регистронезависимые версии функций `coalesce`, `ifNull`, `nullIf` [#2752](https://github.com/yandex/ClickHouse/pull/2752).
+
+### Исправление ошибок:
+* Исправлена возможная ошибка при старте реплики [#2759](https://github.com/yandex/ClickHouse/pull/2759).
+
+
+## ClickHouse release 18.4.0, 2018-07-28
+
+### Новые возможности:
+* Добавлены системные таблицы `formats`, `data_type_families`, `aggregate_function_combinators`, `table_functions`, `table_engines`, `collations` [#2721](https://github.com/yandex/ClickHouse/pull/2721).
+* Добавлена возможность использования табличной функции вместо таблицы в качестве аргумента табличной функции `remote` и `cluster` [#2708](https://github.com/yandex/ClickHouse/pull/2708).
+* Поддержка `HTTP Basic` аутентификации в протоколе репликации [#2727](https://github.com/yandex/ClickHouse/pull/2727).
+* В функции `has` добавлена возможность поиска в массиве значений типа `Enum` по числовому значению [Maxim Khrisanfov](https://github.com/yandex/ClickHouse/pull/2699).
+* Поддержка добавления произвольных разделителей сообщений в процессе чтения из `Kafka` [Amos Bird](https://github.com/yandex/ClickHouse/pull/2701).
+
+### Улучшения:
+* Запрос `ALTER TABLE t DELETE WHERE` не перезаписывает куски данных, которые не были затронуты условием WHERE [#2694](https://github.com/yandex/ClickHouse/pull/2694).
+* Настройка `use_minimalistic_checksums_in_zookeeper` таблиц семейства `ReplicatedMergeTree` включена по-умолчанию. Эта настройка была добавлена в версии 1.1.54378, 2018-04-16. Установка версий, более старых, чем 1.1.54378, становится невозможной.
+* Поддерживается запуск запросов `KILL` и `OPTIMIZE` с указанием `ON CLUSTER` [Winter Zhang](https://github.com/yandex/ClickHouse/pull/2689).
+
+### Исправление ошибок:
+* Исправлена ошибка `Column ... is not under aggregate function and not in GROUP BY` в случае агрегации по выражению с оператором IN. Ошибка появилась в версии 18.1.0. ([bbdd780b](https://github.com/yandex/ClickHouse/commit/bbdd780be0be06a0f336775941cdd536878dd2c2))
+* Исправлена ошибка в агрегатной функции `windowFunnel` [Winter Zhang](https://github.com/yandex/ClickHouse/pull/2735).
+* Исправлена ошибка в агрегатной функции `anyHeavy` ([a2101df2](https://github.com/yandex/ClickHouse/commit/a2101df25a6a0fba99aa71f8793d762af2b801ee))
+* Исправлено падение сервера при использовании функции `countArray()`.
+
+
+## ClickHouse release 18.1.0, 2018-07-23
+
+### Новые возможности:
+* Поддержка запроса `ALTER TABLE t DELETE WHERE` для нереплицированных MergeTree-таблиц ([#2634](https://github.com/yandex/ClickHouse/pull/2634)).
+* Поддержка произвольных типов для семейства агрегатных функций `uniq*` ([#2010](https://github.com/yandex/ClickHouse/issues/2010)).
+* Поддержка произвольных типов в операторах сравнения ([#2026](https://github.com/yandex/ClickHouse/issues/2026)).
+* Возможность в `users.xml` указывать маску подсети в формате `10.0.0.1/255.255.255.0`. Это необходимо для использования "дырявых" масок IPv6 сетей ([#2637](https://github.com/yandex/ClickHouse/pull/2637)).
+* Добавлена функция `arrayDistinct` ([#2670](https://github.com/yandex/ClickHouse/pull/2670)).
+* Движок SummingMergeTree теперь может работать со столбцами типа AggregateFunction ([Constantin S. Pan](https://github.com/yandex/ClickHouse/pull/2566)).
+
+### Улучшения:
+* Изменена схема версионирования релизов. Теперь первый компонент содержит год релиза (A.D.; по московскому времени; из номера вычитается 2000), второй - номер крупных изменений (увеличивается для большинства релизов), третий - патч-версия. Релизы по-прежнему обратно совместимы, если другое не указано в changelog.
+* Ускорено преобразование чисел с плавающей точкой в строку ([Amos Bird](https://github.com/yandex/ClickHouse/pull/2664)).
+* Теперь, если при вставке из-за ошибок парсинга пропущено некоторое количество строк (такое возможно про включённых настройках `input_allow_errors_num`, `input_allow_errors_ratio`), это количество пишется в лог сервера ([Leonardo Cecchi](https://github.com/yandex/ClickHouse/pull/2669)).
+
+### Исправление ошибок:
+* Исправлена работа команды TRUNCATE для временных таблиц ([Amos Bird](https://github.com/yandex/ClickHouse/pull/2624)).
+* Исправлен редкий deadlock в клиентской библиотеке ZooKeeper, который возникал при сетевой ошибке во время вычитывания ответа ([c315200](https://github.com/yandex/ClickHouse/commit/c315200e64b87e44bdf740707fc857d1fdf7e947)).
+* Исправлена ошибка при CAST в Nullable типы ([#1322](https://github.com/yandex/ClickHouse/issues/1322)).
+* Исправлен неправильный результат функции `maxIntersection()` в случае совпадения границ отрезков ([Michael Furmur](https://github.com/yandex/ClickHouse/pull/2657)).
+* Исправлено неверное преобразование цепочки OR-выражений в аргументе функции ([chenxing-xc](https://github.com/yandex/ClickHouse/pull/2663)).
+* Исправлена деградация производительности запросов, содержащих выражение `IN (подзапрос)` внутри другого подзапроса ([#2571](https://github.com/yandex/ClickHouse/issues/2571)).
+* Исправлена несовместимость серверов разных версий при распределённых запросах, использующих функцию `CAST` не в верхнем регистре ([fe8c4d6](https://github.com/yandex/ClickHouse/commit/fe8c4d64e434cacd4ceef34faa9005129f2190a5)).
+* Добавлено недостающее квотирование идентификаторов при запросах к внешним СУБД ([#2635](https://github.com/yandex/ClickHouse/issues/2635)).
+
+### Обратно несовместимые изменения:
+* Не работает преобразование строки, содержащей число ноль, в DateTime. Пример: `SELECT toDateTime('0')`. По той же причине не работает `DateTime DEFAULT '0'` в таблицах, а также `0` в словарях. Решение: заменить `0` на `0000-00-00 00:00:00`.
+
+
## ClickHouse release 1.1.54394, 2018-07-12
### Новые возможности:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3c53d3245a7..f5aee27ddab 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -34,10 +34,9 @@ endif ()
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
message (STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE} )
-# ASan - build type with address sanitizer
-# UBSan - build type with undefined behaviour sanitizer
-# TSan is not supported due to false positive errors in libstdc++ and necessity to rebuild libstdc++ with TSan
-set (CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Debug;Release;MinSizeRel;ASan;UBSan" CACHE STRING "" FORCE)
+set (CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Debug;Release;MinSizeRel" CACHE STRING "" FORCE)
+
+include (cmake/sanitize.cmake)
include (cmake/arch.cmake)
@@ -61,10 +60,6 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set (COMMON_WARNING_FLAGS "${COMMON_WARNING_FLAGS} -Wno-unused-command-line-argument")
endif ()
-if (ARCH_LINUX)
- set (CXX11_ABI "ENABLE" CACHE STRING "Use C++11 ABI: DEFAULT, ENABLE, DISABLE")
-endif ()
-
option (TEST_COVERAGE "Enables flags for test coverage" OFF)
option (ENABLE_TESTS "Enables tests" ${NOT_MSVC})
@@ -86,7 +81,7 @@ endif ()
if (CMAKE_LIBRARY_ARCHITECTURE MATCHES "amd64.*|x86_64.*|AMD64.*")
option (USE_INTERNAL_MEMCPY "Use internal implementation of 'memcpy' function instead of provided by libc. Only for x86_64." ON)
- if (ARCH_LINUX)
+ if (OS_LINUX)
option (GLIBC_COMPATIBILITY "Set to TRUE to enable compatibility with older glibc libraries. Only for x86_64, Linux. Implies USE_INTERNAL_MEMCPY." ON)
endif()
endif ()
@@ -95,15 +90,7 @@ if (GLIBC_COMPATIBILITY)
set (USE_INTERNAL_MEMCPY ON)
endif ()
-if (CXX11_ABI STREQUAL ENABLE)
- set (CXX11_ABI_FLAGS "-D_GLIBCXX_USE_CXX11_ABI=1")
-elseif (CXX11_ABI STREQUAL DISABLE)
- set (CXX11_ABI_FLAGS "-D_GLIBCXX_USE_CXX11_ABI=0")
-else ()
- set (CXX11_ABI_FLAGS "")
-endif ()
-
-set (COMPILER_FLAGS "${COMPILER_FLAGS} ${CXX11_ABI_FLAGS}")
+set (COMPILER_FLAGS "${COMPILER_FLAGS}")
string(REGEX MATCH "-?[0-9]+(.[0-9]+)?$" COMPILER_POSTFIX ${CMAKE_CXX_COMPILER})
@@ -150,26 +137,29 @@ else ()
endif ()
set (CMAKE_BUILD_COLOR_MAKEFILE ON)
-set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_FLAGS} ${PLATFORM_EXTRA_CXX_FLAG} -fno-omit-frame-pointer ${COMMON_WARNING_FLAGS} ${CXX_WARNING_FLAGS} ${GLIBC_COMPATIBILITY_COMPILE_FLAGS}")
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_FLAGS} ${PLATFORM_EXTRA_CXX_FLAG} -fno-omit-frame-pointer ${COMMON_WARNING_FLAGS} ${CXX_WARNING_FLAGS}")
#set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_ADD}")
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 ${CMAKE_CXX_FLAGS_ADD}")
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g3 -ggdb3 -fno-inline ${CMAKE_CXX_FLAGS_ADD}")
-set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILER_FLAGS} -fno-omit-frame-pointer ${COMMON_WARNING_FLAGS} ${GLIBC_COMPATIBILITY_COMPILE_FLAGS} ${CMAKE_C_FLAGS_ADD}")
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILER_FLAGS} -fno-omit-frame-pointer ${COMMON_WARNING_FLAGS} ${CMAKE_C_FLAGS_ADD}")
#set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${CMAKE_C_FLAGS_ADD}")
set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 ${CMAKE_C_FLAGS_ADD}")
set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g3 -ggdb3 -fno-inline ${CMAKE_C_FLAGS_ADD}")
-if (MAKE_STATIC_LIBRARIES AND NOT APPLE AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND ARCH_FREEBSD))
+if (MAKE_STATIC_LIBRARIES AND NOT APPLE AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND OS_FREEBSD))
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
+
+ # Along with executables, we also build example of shared library for "library dictionary source"; and it also should be self-contained.
+ set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc -static-libstdc++")
endif ()
set(THREADS_PREFER_PTHREAD_FLAG ON)
include (cmake/test_compiler.cmake)
-if (ARCH_LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
- set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GLIBC_COMPATIBILITY_LINK_FLAGS} ${CXX11_ABI_FLAGS}")
+if (OS_LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
option (USE_LIBCXX "Use libc++ and libc++abi instead of libstdc++ (only make sense on Linux with Clang)" ${HAVE_LIBCXX})
set (LIBCXX_PATH "" CACHE STRING "Use custom path for libc++. It should be used for MSan.")
@@ -199,8 +189,6 @@ if (NOT MAKE_STATIC_LIBRARIES)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif ()
-include (cmake/sanitize.cmake)
-
# Using "include-what-you-use" tool.
option (USE_INCLUDE_WHAT_YOU_USE "Use 'include-what-you-use' tool" OFF)
if (USE_INCLUDE_WHAT_YOU_USE)
@@ -237,7 +225,7 @@ else ()
set(NOT_UNBUNDLED 1)
endif ()
# Using system libs can cause lot of warnings in includes.
-if (UNBUNDLED OR NOT (ARCH_LINUX OR APPLE) OR ARCH_32)
+if (UNBUNDLED OR NOT (OS_LINUX OR APPLE) OR ARCH_32)
option (NO_WERROR "Disable -Werror compiler option" ON)
endif ()
@@ -246,24 +234,15 @@ message (STATUS "Building for: ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_PROCESSOR} ${CMAKE
include(GNUInstallDirs)
include (cmake/find_ssl.cmake)
-if (NOT OPENSSL_FOUND)
- message (FATAL_ERROR "Need openssl for build. debian tip: sudo apt install libssl-dev")
-endif ()
-
include (cmake/lib_name.cmake)
include (cmake/find_icu4c.cmake)
include (cmake/find_boost.cmake)
-# openssl, zlib before poco
include (cmake/find_zlib.cmake)
include (cmake/find_zstd.cmake)
include (cmake/find_ltdl.cmake) # for odbc
include (cmake/find_termcap.cmake)
-if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/poco/cmake/FindODBC.cmake)
- include (${CMAKE_CURRENT_SOURCE_DIR}/contrib/poco/cmake/FindODBC.cmake) # for poco
-else ()
- include (cmake/find_odbc.cmake)
-endif ()
-message (STATUS "Using odbc: ${ODBC_INCLUDE_DIRECTORIES} : ${ODBC_LIBRARIES}")
+include (cmake/find_odbc.cmake)
+# openssl, zlib, odbc before poco
include (cmake/find_poco.cmake)
include (cmake/find_lz4.cmake)
include (cmake/find_sparsehash.cmake)
@@ -275,6 +254,9 @@ include (cmake/find_rdkafka.cmake)
include (cmake/find_capnp.cmake)
include (cmake/find_llvm.cmake)
include (cmake/find_cpuid.cmake)
+if (ENABLE_TESTS)
+ include (cmake/find_gtest.cmake)
+endif ()
include (cmake/find_contrib_lib.cmake)
find_contrib_lib(cityhash)
diff --git a/README.md b/README.md
index 905e6e5ba90..8cb9fa3379e 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
ClickHouse is an open-source column-oriented database management system that allows generating analytical data reports in real time.
+[![Build Status](https://travis-ci.org/yandex/ClickHouse.svg?branch=master)](https://travis-ci.org/yandex/ClickHouse)
+
## Useful links
* [Official website](https://clickhouse.yandex/) has quick high-level overview of ClickHouse on main page.
@@ -9,5 +11,3 @@ ClickHouse is an open-source column-oriented database management system that all
* [Documentation](https://clickhouse.yandex/docs/en/) provides more in-depth information.
* [Contacts](https://clickhouse.yandex/#contacts) can help to get your questions answered if there are any.
-
-[![Build Status](https://travis-ci.org/yandex/ClickHouse.svg?branch=master)](https://travis-ci.org/yandex/ClickHouse)
diff --git a/ci/install-libraries.sh b/ci/install-libraries.sh
index 4868221b342..d7fb856dbed 100755
--- a/ci/install-libraries.sh
+++ b/ci/install-libraries.sh
@@ -3,11 +3,8 @@ set -e -x
source default-config
-./install-os-packages.sh libssl-dev
./install-os-packages.sh libicu-dev
./install-os-packages.sh libreadline-dev
-./install-os-packages.sh libmariadbclient-dev
-./install-os-packages.sh libunixodbc-dev
if [[ "$ENABLE_EMBEDDED_COMPILER" == 1 && "$USE_LLVM_LIBRARIES_FROM_SYSTEM" == 1 ]]; then
./install-os-packages.sh llvm-libs-5.0
diff --git a/ci/install-os-packages.sh b/ci/install-os-packages.sh
index 4aae6268aa1..fe5b4f84833 100755
--- a/ci/install-os-packages.sh
+++ b/ci/install-os-packages.sh
@@ -43,21 +43,12 @@ case $PACKAGE_MANAGER in
jq)
$SUDO apt-get install -y jq
;;
- libssl-dev)
- $SUDO apt-get install -y libssl-dev
- ;;
libicu-dev)
$SUDO apt-get install -y libicu-dev
;;
libreadline-dev)
$SUDO apt-get install -y libreadline-dev
;;
- libunixodbc-dev)
- $SUDO apt-get install -y unixodbc-dev
- ;;
- libmariadbclient-dev)
- $SUDO apt-get install -y libmariadbclient-dev
- ;;
llvm-libs*)
$SUDO apt-get install -y ${WHAT/llvm-libs/liblld}-dev ${WHAT/llvm-libs/libclang}-dev
;;
@@ -97,22 +88,12 @@ case $PACKAGE_MANAGER in
jq)
$SUDO yum install -y jq
;;
- libssl-dev)
- $SUDO yum install -y openssl-devel
- ;;
libicu-dev)
$SUDO yum install -y libicu-devel
;;
libreadline-dev)
$SUDO yum install -y readline-devel
;;
- libunixodbc-dev)
- $SUDO yum install -y unixODBC-devel libtool-ltdl-devel
- ;;
- libmariadbclient-dev)
- echo "There is no package with static mysqlclient library"; echo 1;
- #$SUDO yum install -y mariadb-connector-c-devel
- ;;
*)
echo "Unknown package"; exit 1;
;;
@@ -146,21 +127,12 @@ case $PACKAGE_MANAGER in
jq)
$SUDO pkg install -y jq
;;
- libssl-dev)
- $SUDO pkg install -y openssl
- ;;
libicu-dev)
$SUDO pkg install -y icu
;;
libreadline-dev)
$SUDO pkg install -y readline
;;
- libunixodbc-dev)
- $SUDO pkg install -y unixODBC libltdl
- ;;
- libmariadbclient-dev)
- $SUDO pkg install -y mariadb102-client
- ;;
*)
echo "Unknown package"; exit 1;
;;
diff --git a/ci/jobs/quick-build/run.sh b/ci/jobs/quick-build/run.sh
index 5fe57457645..6a948c560ee 100755
--- a/ci/jobs/quick-build/run.sh
+++ b/ci/jobs/quick-build/run.sh
@@ -21,7 +21,7 @@ BUILD_TARGETS=clickhouse
BUILD_TYPE=Debug
ENABLE_EMBEDDED_COMPILER=0
-CMAKE_FLAGS="-D CMAKE_C_FLAGS_ADD=-g0 -D CMAKE_CXX_FLAGS_ADD=-g0 -D ENABLE_TCMALLOC=0 -D ENABLE_CAPNP=0 -D ENABLE_RDKAFKA=0 -D ENABLE_UNWIND=0 -D ENABLE_ICU=0 -D ENABLE_POCO_MONGODB=0 -D ENABLE_POCO_NETSSL=0 -D ENABLE_POCO_ODBC=0 -D ENABLE_MYSQL=0"
+CMAKE_FLAGS="-D CMAKE_C_FLAGS_ADD=-g0 -D CMAKE_CXX_FLAGS_ADD=-g0 -D ENABLE_JEMALLOC=0 -D ENABLE_CAPNP=0 -D ENABLE_RDKAFKA=0 -D ENABLE_UNWIND=0 -D ENABLE_ICU=0 -D ENABLE_POCO_MONGODB=0 -D ENABLE_POCO_NETSSL=0 -D ENABLE_POCO_ODBC=0 -D ENABLE_ODBC=0 -D ENABLE_MYSQL=0"
[[ $(uname) == "FreeBSD" ]] && COMPILER_PACKAGE_VERSION=devel && export COMPILER_PATH=/usr/local/bin
diff --git a/cmake/Modules/FindODBC.cmake b/cmake/Modules/FindODBC.cmake
new file mode 100644
index 00000000000..66d43e93d2d
--- /dev/null
+++ b/cmake/Modules/FindODBC.cmake
@@ -0,0 +1,88 @@
+# This file copied from contrib/poco/cmake/FindODBC.cmake to allow build without submodules
+
+#
+# Find the ODBC driver manager includes and library.
+#
+# ODBC is an open standard for connecting to different databases in a
+# semi-vendor-independent fashion. First you install the ODBC driver
+# manager. Then you need a driver for each separate database you want
+# to connect to (unless a generic one works). VTK includes neither
+# the driver manager nor the vendor-specific drivers: you have to find
+# those yourself.
+#
+# This module defines
+# ODBC_INCLUDE_DIRECTORIES, where to find sql.h
+# ODBC_LIBRARIES, the libraries to link against to use ODBC
+# ODBC_FOUND. If false, you cannot build anything that requires ODBC.
+
+option (ENABLE_ODBC "Enable ODBC" ${OS_LINUX})
+if (OS_LINUX)
+ option (USE_INTERNAL_ODBC_LIBRARY "Set to FALSE to use system odbc library instead of bundled" ${NOT_UNBUNDLED})
+else ()
+ option (USE_INTERNAL_ODBC_LIBRARY "Set to FALSE to use system odbc library instead of bundled" OFF)
+endif ()
+
+if (USE_INTERNAL_ODBC_LIBRARY AND NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/unixodbc/README")
+ message (WARNING "submodule contrib/unixodbc is missing. to fix try run: \n git submodule update --init --recursive")
+ set (USE_INTERNAL_ODBC_LIBRARY 0)
+endif ()
+
+if (ENABLE_ODBC)
+ if (USE_INTERNAL_ODBC_LIBRARY)
+ set (ODBC_LIBRARIES unixodbc)
+ set (ODBC_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/contrib/unixodbc/include)
+ set (ODBC_FOUND 1)
+ set (USE_ODBC 1)
+ else ()
+ find_path(ODBC_INCLUDE_DIRECTORIES
+ NAMES sql.h
+ HINTS
+ /usr/include
+ /usr/include/iodbc
+ /usr/include/odbc
+ /usr/local/include
+ /usr/local/include/iodbc
+ /usr/local/include/odbc
+ /usr/local/iodbc/include
+ /usr/local/odbc/include
+ "C:/Program Files/ODBC/include"
+ "C:/Program Files/Microsoft SDKs/Windows/v7.0/include"
+ "C:/Program Files/Microsoft SDKs/Windows/v6.0a/include"
+ "C:/ODBC/include"
+ DOC "Specify the directory containing sql.h."
+ )
+
+ find_library(ODBC_LIBRARIES
+ NAMES iodbc odbc iodbcinst odbcinst odbc32
+ HINTS
+ /usr/lib
+ /usr/lib/iodbc
+ /usr/lib/odbc
+ /usr/local/lib
+ /usr/local/lib/iodbc
+ /usr/local/lib/odbc
+ /usr/local/iodbc/lib
+ /usr/local/odbc/lib
+ "C:/Program Files/ODBC/lib"
+ "C:/ODBC/lib/debug"
+ "C:/Program Files (x86)/Microsoft SDKs/Windows/v7.0A/Lib"
+ DOC "Specify the ODBC driver manager library here."
+ )
+
+ # MinGW find usually fails
+ if(MINGW)
+ set(ODBC_INCLUDE_DIRECTORIES ".")
+ set(ODBC_LIBRARIES odbc32)
+ endif()
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(ODBC
+ DEFAULT_MSG
+ ODBC_INCLUDE_DIRECTORIES
+ ODBC_LIBRARIES)
+
+ mark_as_advanced(ODBC_FOUND ODBC_LIBRARIES ODBC_INCLUDE_DIRECTORIES)
+ endif ()
+endif ()
+
+message (STATUS "Using odbc: ${ODBC_INCLUDE_DIRECTORIES} : ${ODBC_LIBRARIES}")
diff --git a/cmake/arch.cmake b/cmake/arch.cmake
index ba446d95676..65361386035 100644
--- a/cmake/arch.cmake
+++ b/cmake/arch.cmake
@@ -11,19 +11,12 @@ if ( ( ARCH_ARM AND NOT ARCH_AARCH64 ) OR ARCH_I386)
set (ARCH_32 1)
message (WARNING "Support for 32bit platforms is highly experimental")
endif ()
+
if (CMAKE_SYSTEM MATCHES "Linux")
- set (ARCH_LINUX 1)
+ set (OS_LINUX 1)
endif ()
if (CMAKE_SYSTEM MATCHES "FreeBSD")
- set (ARCH_FREEBSD 1)
-endif ()
-
-if (NOT MSVC)
- set (NOT_MSVC 1)
-endif ()
-
-if (NOT APPLE)
- set (NOT_APPLE 1)
+ set (OS_FREEBSD 1)
endif ()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
diff --git a/cmake/find_cpuid.cmake b/cmake/find_cpuid.cmake
index 6a4361dc42c..d02336021bb 100644
--- a/cmake/find_cpuid.cmake
+++ b/cmake/find_cpuid.cmake
@@ -2,7 +2,7 @@
# TODO: test new libcpuid - maybe already fixed
if (NOT ARCH_ARM)
- if (ARCH_FREEBSD)
+ if (OS_FREEBSD)
set (DEFAULT_USE_INTERNAL_CPUID_LIBRARY 1)
else ()
set (DEFAULT_USE_INTERNAL_CPUID_LIBRARY ${NOT_UNBUNDLED})
diff --git a/cmake/find_execinfo.cmake b/cmake/find_execinfo.cmake
index 05dd72dbb3d..650d279983c 100644
--- a/cmake/find_execinfo.cmake
+++ b/cmake/find_execinfo.cmake
@@ -1,4 +1,4 @@
-if (ARCH_FREEBSD)
+if (OS_FREEBSD)
find_library (EXECINFO_LIBRARY execinfo)
find_library (ELF_LIBRARY elf)
message (STATUS "Using execinfo: ${EXECINFO_LIBRARY}")
diff --git a/cmake/find_llvm.cmake b/cmake/find_llvm.cmake
index 6e45f715552..b10a8cb87d4 100644
--- a/cmake/find_llvm.cmake
+++ b/cmake/find_llvm.cmake
@@ -24,6 +24,15 @@ if (ENABLE_EMBEDDED_COMPILER)
endif ()
endif ()
+ if (LLVM_FOUND)
+ find_library (LLD_LIBRARY_TEST lldCore PATHS ${LLVM_LIBRARY_DIRS})
+ find_path (LLD_INCLUDE_DIR_TEST NAMES lld/Core/AbsoluteAtom.h PATHS ${LLVM_INCLUDE_DIRS})
+ if (NOT LLD_LIBRARY_TEST OR NOT LLD_INCLUDE_DIR_TEST)
+ set (LLVM_FOUND 0)
+ message(WARNING "liblld (${LLD_LIBRARY_TEST}, ${LLD_INCLUDE_DIR_TEST}) not found in ${LLVM_INCLUDE_DIRS} ${LLVM_LIBRARY_DIRS}. Disabling internal compiler.")
+ endif ()
+ endif ()
+
if (LLVM_FOUND)
# Remove dynamically-linked zlib and libedit from LLVM's dependencies:
set_target_properties(LLVMSupport PROPERTIES INTERFACE_LINK_LIBRARIES "-lpthread;LLVMDemangle;${ZLIB_LIBRARIES}")
diff --git a/cmake/find_ltdl.cmake b/cmake/find_ltdl.cmake
index 935de0d4124..18003618dbd 100644
--- a/cmake/find_ltdl.cmake
+++ b/cmake/find_ltdl.cmake
@@ -1,3 +1,5 @@
-set (LTDL_PATHS "/usr/local/opt/libtool/lib")
-find_library (LTDL_LIBRARY ltdl PATHS ${LTDL_PATHS})
-message (STATUS "Using ltdl: ${LTDL_LIBRARY}")
+if (ENABLE_ODBC AND NOT USE_INTERNAL_ODBC_LIBRARY)
+ set (LTDL_PATHS "/usr/local/opt/libtool/lib")
+ find_library (LTDL_LIBRARY ltdl PATHS ${LTDL_PATHS})
+ message (STATUS "Using ltdl: ${LTDL_LIBRARY}")
+endif ()
diff --git a/cmake/find_odbc.cmake b/cmake/find_odbc.cmake
index 338108910bf..95acf40b2b4 100644
--- a/cmake/find_odbc.cmake
+++ b/cmake/find_odbc.cmake
@@ -13,54 +13,77 @@
# This module defines
# ODBC_INCLUDE_DIRECTORIES, where to find sql.h
# ODBC_LIBRARIES, the libraries to link against to use ODBC
-# ODBC_FOUND. If false, you cannot build anything that requires MySQL.
+# ODBC_FOUND. If false, you cannot build anything that requires ODBC.
-find_path(ODBC_INCLUDE_DIRECTORIES
- NAMES sql.h
- HINTS
- /usr/include
- /usr/include/odbc
- /usr/include/iodbc
- /usr/local/include
- /usr/local/include/odbc
- /usr/local/include/iodbc
- /usr/local/odbc/include
- /usr/local/iodbc/include
- "C:/Program Files/ODBC/include"
- "C:/Program Files/Microsoft SDKs/Windows/v7.0/include"
- "C:/Program Files/Microsoft SDKs/Windows/v6.0a/include"
- "C:/ODBC/include"
- DOC "Specify the directory containing sql.h."
-)
+option (ENABLE_ODBC "Enable ODBC" ${OS_LINUX})
+if (OS_LINUX)
+ option (USE_INTERNAL_ODBC_LIBRARY "Set to FALSE to use system odbc library instead of bundled" ${NOT_UNBUNDLED})
+else ()
+ option (USE_INTERNAL_ODBC_LIBRARY "Set to FALSE to use system odbc library instead of bundled" OFF)
+endif ()
-find_library(ODBC_LIBRARIES
- NAMES iodbc odbc iodbcinst odbcinst odbc32
- HINTS
- /usr/lib
- /usr/lib/odbc
- /usr/lib/iodbc
- /usr/local/lib
- /usr/local/lib/odbc
- /usr/local/lib/iodbc
- /usr/local/odbc/lib
- /usr/local/iodbc/lib
- "C:/Program Files/ODBC/lib"
- "C:/ODBC/lib/debug"
- "C:/Program Files (x86)/Microsoft SDKs/Windows/v7.0A/Lib"
- DOC "Specify the ODBC driver manager library here."
-)
+if (USE_INTERNAL_ODBC_LIBRARY AND NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/unixodbc/README")
+ message (WARNING "submodule contrib/unixodbc is missing. to fix try run: \n git submodule update --init --recursive")
+ set (USE_INTERNAL_ODBC_LIBRARY 0)
+endif ()
-# MinGW find usually fails
-if(MINGW)
- set(ODBC_INCLUDE_DIRECTORIES ".")
- set(ODBC_LIBRARIES odbc32)
-endif()
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(ODBC
- DEFAULT_MSG
- ODBC_INCLUDE_DIRECTORIES
- ODBC_LIBRARIES
- )
+set (ODBC_INCLUDE_DIRECTORIES ) # Include directories will be either used automatically by target_include_directories or set later.
-mark_as_advanced(ODBC_FOUND ODBC_LIBRARIES ODBC_INCLUDE_DIRECTORIES)
+if (ENABLE_ODBC)
+ if (USE_INTERNAL_ODBC_LIBRARY)
+ set (ODBC_LIBRARIES unixodbc)
+ set (ODBC_FOUND 1)
+ set (USE_ODBC 1)
+ else ()
+ find_path(ODBC_INCLUDE_DIRECTORIES
+ NAMES sql.h
+ HINTS
+ /usr/include
+ /usr/include/iodbc
+ /usr/include/odbc
+ /usr/local/include
+ /usr/local/include/iodbc
+ /usr/local/include/odbc
+ /usr/local/iodbc/include
+ /usr/local/odbc/include
+ "C:/Program Files/ODBC/include"
+ "C:/Program Files/Microsoft SDKs/Windows/v7.0/include"
+ "C:/Program Files/Microsoft SDKs/Windows/v6.0a/include"
+ "C:/ODBC/include"
+ DOC "Specify the directory containing sql.h."
+ )
+
+ find_library(ODBC_LIBRARIES
+ NAMES iodbc odbc iodbcinst odbcinst odbc32
+ HINTS
+ /usr/lib
+ /usr/lib/iodbc
+ /usr/lib/odbc
+ /usr/local/lib
+ /usr/local/lib/iodbc
+ /usr/local/lib/odbc
+ /usr/local/iodbc/lib
+ /usr/local/odbc/lib
+ "C:/Program Files/ODBC/lib"
+ "C:/ODBC/lib/debug"
+ "C:/Program Files (x86)/Microsoft SDKs/Windows/v7.0A/Lib"
+ DOC "Specify the ODBC driver manager library here."
+ )
+
+ # MinGW find usually fails
+ if(MINGW)
+ set(ODBC_INCLUDE_DIRECTORIES ".")
+ set(ODBC_LIBRARIES odbc32)
+ endif()
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(ODBC
+ DEFAULT_MSG
+ ODBC_INCLUDE_DIRECTORIES
+ ODBC_LIBRARIES)
+
+ mark_as_advanced(ODBC_FOUND ODBC_LIBRARIES ODBC_INCLUDE_DIRECTORIES)
+ endif ()
+endif ()
+
+message (STATUS "Using odbc: ${ODBC_INCLUDE_DIRECTORIES} : ${ODBC_LIBRARIES}")
diff --git a/cmake/find_poco.cmake b/cmake/find_poco.cmake
index 947d31951c9..f0bc535f614 100644
--- a/cmake/find_poco.cmake
+++ b/cmake/find_poco.cmake
@@ -92,8 +92,7 @@ elseif (NOT MISSING_INTERNAL_POCO_LIBRARY)
endif ()
endif ()
- # TODO! fix internal ssl
- if (OPENSSL_FOUND AND NOT USE_INTERNAL_SSL_LIBRARY AND (NOT DEFINED ENABLE_POCO_NETSSL OR ENABLE_POCO_NETSSL))
+ if (OPENSSL_FOUND AND (NOT DEFINED ENABLE_POCO_NETSSL OR ENABLE_POCO_NETSSL))
set (Poco_NetSSL_LIBRARY PocoNetSSL)
set (Poco_Crypto_LIBRARY PocoCrypto)
endif ()
diff --git a/cmake/find_rdkafka.cmake b/cmake/find_rdkafka.cmake
index 396be18cd1c..f05ced94707 100644
--- a/cmake/find_rdkafka.cmake
+++ b/cmake/find_rdkafka.cmake
@@ -13,7 +13,7 @@ endif ()
if (NOT USE_INTERNAL_RDKAFKA_LIBRARY)
find_library (RDKAFKA_LIB rdkafka)
find_path (RDKAFKA_INCLUDE_DIR NAMES librdkafka/rdkafka.h PATHS ${RDKAFKA_INCLUDE_PATHS})
- if (USE_STATIC_LIBRARIES AND NOT ARCH_FREEBSD)
+ if (USE_STATIC_LIBRARIES AND NOT OS_FREEBSD)
find_library (SASL2_LIBRARY sasl2)
endif ()
endif ()
diff --git a/cmake/find_rt.cmake b/cmake/find_rt.cmake
index 82ec314d195..25614fe55eb 100644
--- a/cmake/find_rt.cmake
+++ b/cmake/find_rt.cmake
@@ -1,7 +1,7 @@
if (APPLE)
# lib from libs/libcommon
set (RT_LIBRARY "apple_rt")
-elseif (ARCH_FREEBSD)
+elseif (OS_FREEBSD)
find_library (RT_LIBRARY rt)
else ()
set (RT_LIBRARY "")
diff --git a/cmake/find_ssl.cmake b/cmake/find_ssl.cmake
index ec40e498da1..51e869f86ea 100644
--- a/cmake/find_ssl.cmake
+++ b/cmake/find_ssl.cmake
@@ -1,4 +1,4 @@
-option (USE_INTERNAL_SSL_LIBRARY "Set to FALSE to use system *ssl library instead of bundled" ${MSVC})
+option (USE_INTERNAL_SSL_LIBRARY "Set to FALSE to use system *ssl library instead of bundled" ${OS_LINUX})
set (OPENSSL_USE_STATIC_LIBS ${USE_STATIC_LIBRARIES})
diff --git a/cmake/find_zlib.cmake b/cmake/find_zlib.cmake
index 17350f9fd58..0e198c9bb0f 100644
--- a/cmake/find_zlib.cmake
+++ b/cmake/find_zlib.cmake
@@ -17,7 +17,7 @@ if (NOT ZLIB_FOUND)
set (USE_INTERNAL_ZLIB_LIBRARY 1)
set (ZLIB_COMPAT 1) # for zlib-ng, also enables WITH_GZFILEOP
set (WITH_NATIVE_INSTRUCTIONS ${ARCHNATIVE})
- if (ARCH_FREEBSD OR ARCH_I386)
+ if (OS_FREEBSD OR ARCH_I386)
set (WITH_OPTIM 0 CACHE INTERNAL "") # Bug in assembler
endif ()
if (ARCH_AARCH64)
diff --git a/cmake/sanitize.cmake b/cmake/sanitize.cmake
index bac27578663..a90533345e6 100644
--- a/cmake/sanitize.cmake
+++ b/cmake/sanitize.cmake
@@ -1,27 +1,37 @@
+option (SANITIZE "Enable sanitizer: address, memory, thread, undefined" "")
+
set (SAN_FLAGS "${SAN_FLAGS} -g -fno-omit-frame-pointer -DSANITIZER")
-if (SAN_DEBUG)
- set (SAN_FLAGS "${SAN_FLAGS} -O0")
-else ()
- set (SAN_FLAGS "${SAN_FLAGS} -O3")
-endif ()
-set (CMAKE_CXX_FLAGS_ASAN "${CMAKE_CXX_FLAGS_ASAN} ${SAN_FLAGS} -fsanitize=address")
-set (CMAKE_C_FLAGS_ASAN "${CMAKE_C_FLAGS_ASAN} ${SAN_FLAGS} -fsanitize=address")
-set (CMAKE_EXE_LINKER_FLAGS_ASAN "${CMAKE_EXE_LINKER_FLAGS_ASAN} -fsanitize=address")
-set (CMAKE_CXX_FLAGS_UBSAN "${CMAKE_CXX_FLAGS_UBSAN} ${SAN_FLAGS} -fsanitize=undefined")
-set (CMAKE_C_FLAGS_UBSAN "${CMAKE_C_FLAGS_UBSAN} ${SAN_FLAGS} -fsanitize=undefined")
-set (CMAKE_EXE_LINKER_FLAGS_UBSAN "${CMAKE_EXE_LINKER_FLAGS_UBSAN} -fsanitize=undefined")
-set (CMAKE_CXX_FLAGS_MSAN "${CMAKE_CXX_FLAGS_MSAN} ${SAN_FLAGS} -fsanitize=memory")
-set (CMAKE_C_FLAGS_MSAN "${CMAKE_C_FLAGS_MSAN} ${SAN_FLAGS} -fsanitize=memory")
-set (CMAKE_EXE_LINKER_FLAGS_MSAN "${CMAKE_EXE_LINKER_FLAGS_MSAN} -fsanitize=memory")
-set (CMAKE_CXX_FLAGS_TSAN "${CMAKE_CXX_FLAGS_TSAN} ${SAN_FLAGS} -fsanitize=thread")
-set (CMAKE_C_FLAGS_TSAN "${CMAKE_C_FLAGS_TSAN} ${SAN_FLAGS} -fsanitize=thread")
-set (CMAKE_EXE_LINKER_FLAGS_TSAN "${CMAKE_EXE_LINKER_FLAGS_TSAN} -fsanitize=thread")
-
-# clang use static linking by default
-if (MAKE_STATIC_LIBRARIES AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
- set (CMAKE_EXE_LINKER_FLAGS_ASAN "${CMAKE_EXE_LINKER_FLAGS_ASAN} -static-libasan")
- set (CMAKE_EXE_LINKER_FLAGS_UBSAN "${CMAKE_EXE_LINKER_FLAGS_UBSAN} -static-libubsan")
- set (CMAKE_EXE_LINKER_FLAGS_MSAN "${CMAKE_EXE_LINKER_FLAGS_MSAN} -static-libmsan")
- set (CMAKE_EXE_LINKER_FLAGS_TSAN "${CMAKE_EXE_LINKER_FLAGS_TSAN} -static-libtsan")
-endif ()
+if (SANITIZE)
+ if (SANITIZE STREQUAL "address")
+ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SAN_FLAGS} -fsanitize=address")
+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SAN_FLAGS} -fsanitize=address")
+ set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
+ if (MAKE_STATIC_LIBRARIES AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan")
+ endif ()
+ elseif (SANITIZE STREQUAL "memory")
+ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SAN_FLAGS} -fsanitize=memory")
+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SAN_FLAGS} -fsanitize=memory")
+ set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=memory")
+ if (MAKE_STATIC_LIBRARIES AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libmsan")
+ endif ()
+ elseif (SANITIZE STREQUAL "thread")
+ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SAN_FLAGS} -fsanitize=thread")
+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SAN_FLAGS} -fsanitize=thread")
+ set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
+ if (MAKE_STATIC_LIBRARIES AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libtsan")
+ endif ()
+ elseif (SANITIZE STREQUAL "undefined")
+ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SAN_FLAGS} -fsanitize=undefined")
+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SAN_FLAGS} -fsanitize=undefined")
+ set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined")
+ if (MAKE_STATIC_LIBRARIES AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libubsan")
+ endif ()
+ else ()
+ message (FATAL_ERROR "Unknown sanitizer type: ${SANITIZE}")
+ endif ()
+endif()
diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt
index e2e4341e1bd..3c0e284e3b9 100644
--- a/contrib/CMakeLists.txt
+++ b/contrib/CMakeLists.txt
@@ -1,5 +1,11 @@
-if (NOT MSVC)
- set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-old-style-cast -Wno-unused-function -Wno-deprecated-declarations -Wno-non-virtual-dtor -std=c++1z")
+# Third-party libraries may have substandard code.
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unused-result -Wno-deprecated-declarations -Wno-maybe-uninitialized -Wno-format -Wno-misleading-indentation")
+ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-old-style-cast -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unused-result -Wno-deprecated-declarations -Wno-non-virtual-dtor -Wno-maybe-uninitialized -Wno-format -Wno-misleading-indentation -std=c++1z")
+elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function -Wno-unused-variable -Wno-unused-result -Wno-deprecated-declarations -Wno-format")
+ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-old-style-cast -Wno-unused-function -Wno-unused-variable -Wno-unused-result -Wno-deprecated-declarations -Wno-non-virtual-dtor -Wno-format -std=c++1z")
endif ()
if (USE_INTERNAL_BOOST_LIBRARY)
@@ -37,6 +43,8 @@ if (USE_INTERNAL_METROHASH_LIBRARY)
add_subdirectory (libmetrohash)
endif ()
+add_subdirectory (murmurhash)
+
if (USE_INTERNAL_BTRIE_LIBRARY)
add_subdirectory (libbtrie)
endif ()
@@ -75,6 +83,10 @@ if (ENABLE_TCMALLOC AND USE_INTERNAL_GPERFTOOLS_LIBRARY)
add_subdirectory (libtcmalloc)
endif ()
+if (ENABLE_JEMALLOC AND USE_INTERNAL_JEMALLOC_LIBRARY)
+ add_subdirectory (jemalloc-cmake)
+endif ()
+
if (USE_INTERNAL_CPUID_LIBRARY)
add_subdirectory (libcpuid)
endif ()
@@ -84,11 +96,18 @@ if (USE_INTERNAL_SSL_LIBRARY)
set (BUILD_SHARED 1)
endif ()
set (USE_SHARED ${USE_STATIC_LIBRARIES})
+ set (LIBRESSL_SKIP_INSTALL 1)
add_subdirectory (ssl)
target_include_directories(${OPENSSL_CRYPTO_LIBRARY} PUBLIC ${OPENSSL_INCLUDE_DIR})
target_include_directories(${OPENSSL_SSL_LIBRARY} PUBLIC ${OPENSSL_INCLUDE_DIR})
endif ()
+if (ENABLE_MYSQL AND USE_INTERNAL_MYSQL_LIBRARY)
+ add_subdirectory (mariadb-connector-c-cmake)
+ target_include_directories(mysqlclient PRIVATE BEFORE ${ZLIB_INCLUDE_DIR})
+ target_include_directories(mysqlclient PRIVATE BEFORE ${OPENSSL_INCLUDE_DIR})
+endif ()
+
if (USE_INTERNAL_RDKAFKA_LIBRARY)
set (RDKAFKA_BUILD_EXAMPLES OFF CACHE INTERNAL "")
set (RDKAFKA_BUILD_TESTS OFF CACHE INTERNAL "")
@@ -112,6 +131,10 @@ if (USE_INTERNAL_RDKAFKA_LIBRARY)
target_include_directories(rdkafka PRIVATE BEFORE ${ZLIB_INCLUDE_DIR})
endif ()
+if (ENABLE_ODBC AND USE_INTERNAL_ODBC_LIBRARY)
+ add_subdirectory (unixodbc-cmake)
+endif ()
+
if (USE_INTERNAL_CAPNP_LIBRARY)
set (BUILD_TESTING 0 CACHE INTERNAL "")
set (_save ${CMAKE_CXX_EXTENSIONS})
@@ -128,11 +151,6 @@ if (USE_INTERNAL_POCO_LIBRARY)
set (_save ${ENABLE_TESTS})
set (ENABLE_TESTS 0)
set (CMAKE_DISABLE_FIND_PACKAGE_ZLIB 1)
- if (USE_INTERNAL_SSL_LIBRARY OR (DEFINED ENABLE_POCO_NETSSL AND NOT ENABLE_POCO_NETSSL))
- set (DISABLE_INTERNAL_OPENSSL 1 CACHE INTERNAL "")
- set (ENABLE_NETSSL 0 CACHE INTERNAL "") # TODO!
- set (ENABLE_CRYPTO 0 CACHE INTERNAL "") # TODO!
- endif ()
if (MSVC)
set (ENABLE_DATA_ODBC 0 CACHE INTERNAL "") # TODO (build fail)
endif ()
diff --git a/contrib/jemalloc b/contrib/jemalloc
new file mode 160000
index 00000000000..41b7372eade
--- /dev/null
+++ b/contrib/jemalloc
@@ -0,0 +1 @@
+Subproject commit 41b7372eadee941b9164751b8d4963f915d3ceae
diff --git a/contrib/jemalloc-cmake/CMakeLists.txt b/contrib/jemalloc-cmake/CMakeLists.txt
new file mode 100644
index 00000000000..d60d34604a9
--- /dev/null
+++ b/contrib/jemalloc-cmake/CMakeLists.txt
@@ -0,0 +1,52 @@
+set(JEMALLOC_SOURCE_DIR ${CMAKE_SOURCE_DIR}/contrib/jemalloc)
+
+set(SRCS
+${JEMALLOC_SOURCE_DIR}/src/arena.c
+${JEMALLOC_SOURCE_DIR}/src/background_thread.c
+${JEMALLOC_SOURCE_DIR}/src/base.c
+${JEMALLOC_SOURCE_DIR}/src/bin.c
+${JEMALLOC_SOURCE_DIR}/src/bitmap.c
+${JEMALLOC_SOURCE_DIR}/src/ckh.c
+${JEMALLOC_SOURCE_DIR}/src/ctl.c
+${JEMALLOC_SOURCE_DIR}/src/div.c
+${JEMALLOC_SOURCE_DIR}/src/extent.c
+${JEMALLOC_SOURCE_DIR}/src/extent_dss.c
+${JEMALLOC_SOURCE_DIR}/src/extent_mmap.c
+${JEMALLOC_SOURCE_DIR}/src/hash.c
+${JEMALLOC_SOURCE_DIR}/src/hook.c
+${JEMALLOC_SOURCE_DIR}/src/jemalloc.c
+${JEMALLOC_SOURCE_DIR}/src/jemalloc_cpp.cpp
+${JEMALLOC_SOURCE_DIR}/src/large.c
+${JEMALLOC_SOURCE_DIR}/src/log.c
+${JEMALLOC_SOURCE_DIR}/src/malloc_io.c
+${JEMALLOC_SOURCE_DIR}/src/mutex.c
+${JEMALLOC_SOURCE_DIR}/src/mutex_pool.c
+${JEMALLOC_SOURCE_DIR}/src/nstime.c
+${JEMALLOC_SOURCE_DIR}/src/pages.c
+${JEMALLOC_SOURCE_DIR}/src/prng.c
+${JEMALLOC_SOURCE_DIR}/src/prof.c
+${JEMALLOC_SOURCE_DIR}/src/rtree.c
+${JEMALLOC_SOURCE_DIR}/src/sc.c
+${JEMALLOC_SOURCE_DIR}/src/stats.c
+${JEMALLOC_SOURCE_DIR}/src/sz.c
+${JEMALLOC_SOURCE_DIR}/src/tcache.c
+${JEMALLOC_SOURCE_DIR}/src/test_hooks.c
+${JEMALLOC_SOURCE_DIR}/src/ticker.c
+${JEMALLOC_SOURCE_DIR}/src/tsd.c
+${JEMALLOC_SOURCE_DIR}/src/witness.c
+)
+
+if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
+ list(APPEND SRCS ${JEMALLOC_SOURCE_DIR}/src/zone.c)
+endif()
+
+add_library(jemalloc STATIC ${SRCS})
+
+target_include_directories(jemalloc PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/include_linux_x86_64) # jemalloc.h
+
+target_include_directories(jemalloc PRIVATE
+ ${JEMALLOC_SOURCE_DIR}/include)
+
+target_compile_definitions(jemalloc PRIVATE -DJEMALLOC_NO_PRIVATE_NAMESPACE)
diff --git a/contrib/jemalloc-cmake/README b/contrib/jemalloc-cmake/README
new file mode 100644
index 00000000000..0af9c4f0e45
--- /dev/null
+++ b/contrib/jemalloc-cmake/README
@@ -0,0 +1 @@
+It allows to integrate JEMalloc into CMake project.
diff --git a/contrib/jemalloc-cmake/include/jemalloc/jemalloc.h b/contrib/jemalloc-cmake/include/jemalloc/jemalloc.h
new file mode 100644
index 00000000000..d06243c5239
--- /dev/null
+++ b/contrib/jemalloc-cmake/include/jemalloc/jemalloc.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/contrib/jemalloc-cmake/include/jemalloc/jemalloc_rename.h b/contrib/jemalloc-cmake/include/jemalloc/jemalloc_rename.h
new file mode 100644
index 00000000000..a2ea2dd3533
--- /dev/null
+++ b/contrib/jemalloc-cmake/include/jemalloc/jemalloc_rename.h
@@ -0,0 +1,29 @@
+/*
+ * Name mangling for public symbols is controlled by --with-mangling and
+ * --with-jemalloc-prefix. With default settings the je_ prefix is stripped by
+ * these macro definitions.
+ */
+#ifndef JEMALLOC_NO_RENAME
+# define je_aligned_alloc aligned_alloc
+# define je_calloc calloc
+# define je_dallocx dallocx
+# define je_free free
+# define je_mallctl mallctl
+# define je_mallctlbymib mallctlbymib
+# define je_mallctlnametomib mallctlnametomib
+# define je_malloc malloc
+# define je_malloc_conf malloc_conf
+# define je_malloc_message malloc_message
+# define je_malloc_stats_print malloc_stats_print
+# define je_malloc_usable_size malloc_usable_size
+# define je_mallocx mallocx
+# define je_nallocx nallocx
+# define je_posix_memalign posix_memalign
+# define je_rallocx rallocx
+# define je_realloc realloc
+# define je_sallocx sallocx
+# define je_sdallocx sdallocx
+# define je_xallocx xallocx
+# define je_memalign memalign
+# define je_valloc valloc
+#endif
diff --git a/contrib/jemalloc-cmake/include_linux_x86_64/README b/contrib/jemalloc-cmake/include_linux_x86_64/README
new file mode 100644
index 00000000000..bf7663bda8d
--- /dev/null
+++ b/contrib/jemalloc-cmake/include_linux_x86_64/README
@@ -0,0 +1,7 @@
+Here are pre-generated files from jemalloc on Linux x86_64.
+You can obtain these files by running ./autogen.sh inside jemalloc source directory.
+
+Added #define GNU_SOURCE
+Added JEMALLOC_OVERRIDE___POSIX_MEMALIGN because why not.
+Removed JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF because it's non standard.
+Removed JEMALLOC_PURGE_MADVISE_FREE because it's available only from Linux 4.5.
diff --git a/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/internal/jemalloc_internal_defs.h b/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/internal/jemalloc_internal_defs.h
new file mode 100644
index 00000000000..43936e8eba0
--- /dev/null
+++ b/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/internal/jemalloc_internal_defs.h
@@ -0,0 +1,373 @@
+/* include/jemalloc/internal/jemalloc_internal_defs.h. Generated from jemalloc_internal_defs.h.in by configure. */
+#ifndef JEMALLOC_INTERNAL_DEFS_H_
+#define JEMALLOC_INTERNAL_DEFS_H_
+
+#ifndef _GNU_SOURCE
+ #define _GNU_SOURCE
+#endif
+
+/*
+ * If JEMALLOC_PREFIX is defined via --with-jemalloc-prefix, it will cause all
+ * public APIs to be prefixed. This makes it possible, with some care, to use
+ * multiple allocators simultaneously.
+ */
+/* #undef JEMALLOC_PREFIX */
+/* #undef JEMALLOC_CPREFIX */
+
+/*
+ * Define overrides for non-standard allocator-related functions if they are
+ * present on the system.
+ */
+#define JEMALLOC_OVERRIDE___LIBC_CALLOC
+#define JEMALLOC_OVERRIDE___LIBC_FREE
+#define JEMALLOC_OVERRIDE___LIBC_MALLOC
+#define JEMALLOC_OVERRIDE___LIBC_MEMALIGN
+#define JEMALLOC_OVERRIDE___LIBC_REALLOC
+#define JEMALLOC_OVERRIDE___LIBC_VALLOC
+#define JEMALLOC_OVERRIDE___POSIX_MEMALIGN
+
+/*
+ * JEMALLOC_PRIVATE_NAMESPACE is used as a prefix for all library-private APIs.
+ * For shared libraries, symbol visibility mechanisms prevent these symbols
+ * from being exported, but for static libraries, naming collisions are a real
+ * possibility.
+ */
+#define JEMALLOC_PRIVATE_NAMESPACE je_
+
+/*
+ * Hyper-threaded CPUs may need a special instruction inside spin loops in
+ * order to yield to another virtual CPU.
+ */
+#define CPU_SPINWAIT __asm__ volatile("pause")
+/* 1 if CPU_SPINWAIT is defined, 0 otherwise. */
+#define HAVE_CPU_SPINWAIT 1
+
+/*
+ * Number of significant bits in virtual addresses. This may be less than the
+ * total number of bits in a pointer, e.g. on x64, for which the uppermost 16
+ * bits are the same as bit 47.
+ */
+#define LG_VADDR 48
+
+/* Defined if C11 atomics are available. */
+#define JEMALLOC_C11_ATOMICS 1
+
+/* Defined if GCC __atomic atomics are available. */
+#define JEMALLOC_GCC_ATOMIC_ATOMICS 1
+
+/* Defined if GCC __sync atomics are available. */
+#define JEMALLOC_GCC_SYNC_ATOMICS 1
+
+/*
+ * Defined if __sync_add_and_fetch(uint32_t *, uint32_t) and
+ * __sync_sub_and_fetch(uint32_t *, uint32_t) are available, despite
+ * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 not being defined (which means the
+ * functions are defined in libgcc instead of being inlines).
+ */
+/* #undef JE_FORCE_SYNC_COMPARE_AND_SWAP_4 */
+
+/*
+ * Defined if __sync_add_and_fetch(uint64_t *, uint64_t) and
+ * __sync_sub_and_fetch(uint64_t *, uint64_t) are available, despite
+ * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 not being defined (which means the
+ * functions are defined in libgcc instead of being inlines).
+ */
+/* #undef JE_FORCE_SYNC_COMPARE_AND_SWAP_8 */
+
+/*
+ * Defined if __builtin_clz() and __builtin_clzl() are available.
+ */
+#define JEMALLOC_HAVE_BUILTIN_CLZ
+
+/*
+ * Defined if os_unfair_lock_*() functions are available, as provided by Darwin.
+ */
+/* #undef JEMALLOC_OS_UNFAIR_LOCK */
+
+/*
+ * Defined if OSSpin*() functions are available, as provided by Darwin, and
+ * documented in the spinlock(3) manual page.
+ */
+/* #undef JEMALLOC_OSSPIN */
+
+/* Defined if syscall(2) is usable. */
+#define JEMALLOC_USE_SYSCALL
+
+/*
+ * Defined if secure_getenv(3) is available.
+ */
+// Don't want dependency on newer GLIBC
+//#define JEMALLOC_HAVE_SECURE_GETENV
+
+/*
+ * Defined if issetugid(2) is available.
+ */
+/* #undef JEMALLOC_HAVE_ISSETUGID */
+
+/* Defined if pthread_atfork(3) is available. */
+#define JEMALLOC_HAVE_PTHREAD_ATFORK
+
+/* Defined if pthread_setname_np(3) is available. */
+#define JEMALLOC_HAVE_PTHREAD_SETNAME_NP
+
+/*
+ * Defined if clock_gettime(CLOCK_MONOTONIC_COARSE, ...) is available.
+ */
+#define JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE 1
+
+/*
+ * Defined if clock_gettime(CLOCK_MONOTONIC, ...) is available.
+ */
+#define JEMALLOC_HAVE_CLOCK_MONOTONIC 1
+
+/*
+ * Defined if mach_absolute_time() is available.
+ */
+/* #undef JEMALLOC_HAVE_MACH_ABSOLUTE_TIME */
+
+/*
+ * Defined if _malloc_thread_cleanup() exists. At least in the case of
+ * FreeBSD, pthread_key_create() allocates, which if used during malloc
+ * bootstrapping will cause recursion into the pthreads library. Therefore, if
+ * _malloc_thread_cleanup() exists, use it as the basis for thread cleanup in
+ * malloc_tsd.
+ */
+/* #undef JEMALLOC_MALLOC_THREAD_CLEANUP */
+
+/*
+ * Defined if threaded initialization is known to be safe on this platform.
+ * Among other things, it must be possible to initialize a mutex without
+ * triggering allocation in order for threaded allocation to be safe.
+ */
+#define JEMALLOC_THREADED_INIT
+
+/*
+ * Defined if the pthreads implementation defines
+ * _pthread_mutex_init_calloc_cb(), in which case the function is used in order
+ * to avoid recursive allocation during mutex initialization.
+ */
+/* #undef JEMALLOC_MUTEX_INIT_CB */
+
+/* Non-empty if the tls_model attribute is supported. */
+#define JEMALLOC_TLS_MODEL __attribute__((tls_model("initial-exec")))
+
+/*
+ * JEMALLOC_DEBUG enables assertions and other sanity checks, and disables
+ * inline functions.
+ */
+/* #undef JEMALLOC_DEBUG */
+
+/* JEMALLOC_STATS enables statistics calculation. */
+#define JEMALLOC_STATS
+
+/* JEMALLOC_PROF enables allocation profiling. */
+/* #undef JEMALLOC_PROF */
+
+/* Use libunwind for profile backtracing if defined. */
+/* #undef JEMALLOC_PROF_LIBUNWIND */
+
+/* Use libgcc for profile backtracing if defined. */
+/* #undef JEMALLOC_PROF_LIBGCC */
+
+/* Use gcc intrinsics for profile backtracing if defined. */
+/* #undef JEMALLOC_PROF_GCC */
+
+/*
+ * JEMALLOC_DSS enables use of sbrk(2) to allocate extents from the data storage
+ * segment (DSS).
+ */
+#define JEMALLOC_DSS
+
+/* Support memory filling (junk/zero). */
+#define JEMALLOC_FILL
+
+/* Support utrace(2)-based tracing. */
+/* #undef JEMALLOC_UTRACE */
+
+/* Support optional abort() on OOM. */
+/* #undef JEMALLOC_XMALLOC */
+
+/* Support lazy locking (avoid locking unless a second thread is launched). */
+/* #undef JEMALLOC_LAZY_LOCK */
+
+/*
+ * Minimum allocation alignment is 2^LG_QUANTUM bytes (ignoring tiny size
+ * classes).
+ */
+/* #undef LG_QUANTUM */
+
+/* One page is 2^LG_PAGE bytes. */
+#define LG_PAGE 12
+
+/*
+ * One huge page is 2^LG_HUGEPAGE bytes. Note that this is defined even if the
+ * system does not explicitly support huge pages; system calls that require
+ * explicit huge page support are separately configured.
+ */
+#define LG_HUGEPAGE 21
+
+/*
+ * If defined, adjacent virtual memory mappings with identical attributes
+ * automatically coalesce, and they fragment when changes are made to subranges.
+ * This is the normal order of things for mmap()/munmap(), but on Windows
+ * VirtualAlloc()/VirtualFree() operations must be precisely matched, i.e.
+ * mappings do *not* coalesce/fragment.
+ */
+#define JEMALLOC_MAPS_COALESCE
+
+/*
+ * If defined, retain memory for later reuse by default rather than using e.g.
+ * munmap() to unmap freed extents. This is enabled on 64-bit Linux because
+ * common sequences of mmap()/munmap() calls will cause virtual memory map
+ * holes.
+ */
+#define JEMALLOC_RETAIN
+
+/* TLS is used to map arenas and magazine caches to threads. */
+#define JEMALLOC_TLS
+
+/*
+ * Used to mark unreachable code to quiet "end of non-void" compiler warnings.
+ * Don't use this directly; instead use unreachable() from util.h
+ */
+#define JEMALLOC_INTERNAL_UNREACHABLE __builtin_unreachable
+
+/*
+ * ffs*() functions to use for bitmapping. Don't use these directly; instead,
+ * use ffs_*() from util.h.
+ */
+#define JEMALLOC_INTERNAL_FFSLL __builtin_ffsll
+#define JEMALLOC_INTERNAL_FFSL __builtin_ffsl
+#define JEMALLOC_INTERNAL_FFS __builtin_ffs
+
+/*
+ * If defined, explicitly attempt to more uniformly distribute large allocation
+ * pointer alignments across all cache indices.
+ */
+#define JEMALLOC_CACHE_OBLIVIOUS
+
+/*
+ * If defined, enable logging facilities. We make this a configure option to
+ * avoid taking extra branches everywhere.
+ */
+/* #undef JEMALLOC_LOG */
+
+/*
+ * Darwin (OS X) uses zones to work around Mach-O symbol override shortcomings.
+ */
+/* #undef JEMALLOC_ZONE */
+
+/*
+ * Methods for determining whether the OS overcommits.
+ * JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY: Linux's
+ * /proc/sys/vm.overcommit_memory file.
+ * JEMALLOC_SYSCTL_VM_OVERCOMMIT: FreeBSD's vm.overcommit sysctl.
+ */
+/* #undef JEMALLOC_SYSCTL_VM_OVERCOMMIT */
+#define JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY
+
+/* Defined if madvise(2) is available. */
+#define JEMALLOC_HAVE_MADVISE
+
+/*
+ * Defined if transparent huge pages are supported via the MADV_[NO]HUGEPAGE
+ * arguments to madvise(2).
+ */
+#define JEMALLOC_HAVE_MADVISE_HUGE
+
+/*
+ * Methods for purging unused pages differ between operating systems.
+ *
+ * madvise(..., MADV_FREE) : This marks pages as being unused, such that they
+ * will be discarded rather than swapped out.
+ * madvise(..., MADV_DONTNEED) : If JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS is
+ * defined, this immediately discards pages,
+ * such that new pages will be demand-zeroed if
+ * the address region is later touched;
+ * otherwise this behaves similarly to
+ * MADV_FREE, though typically with higher
+ * system overhead.
+ */
+//#define JEMALLOC_PURGE_MADVISE_FREE
+#define JEMALLOC_PURGE_MADVISE_DONTNEED
+#define JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS
+
+/* Defined if madvise(2) is available but MADV_FREE is not (x86 Linux only). */
+/* #undef JEMALLOC_DEFINE_MADVISE_FREE */
+
+/*
+ * Defined if MADV_DO[NT]DUMP is supported as an argument to madvise.
+ */
+#define JEMALLOC_MADVISE_DONTDUMP
+
+/*
+ * Defined if transparent huge pages (THPs) are supported via the
+ * MADV_[NO]HUGEPAGE arguments to madvise(2), and THP support is enabled.
+ */
+/* #undef JEMALLOC_THP */
+
+/* Define if operating system has alloca.h header. */
+#define JEMALLOC_HAS_ALLOCA_H 1
+
+/* C99 restrict keyword supported. */
+#define JEMALLOC_HAS_RESTRICT 1
+
+/* For use by hash code. */
+/* #undef JEMALLOC_BIG_ENDIAN */
+
+/* sizeof(int) == 2^LG_SIZEOF_INT. */
+#define LG_SIZEOF_INT 2
+
+/* sizeof(long) == 2^LG_SIZEOF_LONG. */
+#define LG_SIZEOF_LONG 3
+
+/* sizeof(long long) == 2^LG_SIZEOF_LONG_LONG. */
+#define LG_SIZEOF_LONG_LONG 3
+
+/* sizeof(intmax_t) == 2^LG_SIZEOF_INTMAX_T. */
+#define LG_SIZEOF_INTMAX_T 3
+
+/* glibc malloc hooks (__malloc_hook, __realloc_hook, __free_hook). */
+#define JEMALLOC_GLIBC_MALLOC_HOOK
+
+/* glibc memalign hook. */
+#define JEMALLOC_GLIBC_MEMALIGN_HOOK
+
+/* pthread support */
+#define JEMALLOC_HAVE_PTHREAD
+
+/* dlsym() support */
+#define JEMALLOC_HAVE_DLSYM
+
+/* Adaptive mutex support in pthreads. */
+#define JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP
+
+/* GNU specific sched_getcpu support */
+#define JEMALLOC_HAVE_SCHED_GETCPU
+
+/* GNU specific sched_setaffinity support */
+#define JEMALLOC_HAVE_SCHED_SETAFFINITY
+
+/*
+ * If defined, all the features necessary for background threads are present.
+ */
+#define JEMALLOC_BACKGROUND_THREAD 1
+
+/*
+ * If defined, jemalloc symbols are not exported (doesn't work when
+ * JEMALLOC_PREFIX is not defined).
+ */
+/* #undef JEMALLOC_EXPORT */
+
+/* config.malloc_conf options string. */
+#define JEMALLOC_CONFIG_MALLOC_CONF ""
+
+/* If defined, jemalloc takes the malloc/free/etc. symbol names. */
+#define JEMALLOC_IS_MALLOC 1
+
+/*
+ * Defined if strerror_r returns char * if _GNU_SOURCE is defined.
+ */
+#define JEMALLOC_STRERROR_R_RETURNS_CHAR_WITH_GNU_SOURCE
+
+#endif /* JEMALLOC_INTERNAL_DEFS_H_ */
diff --git a/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/internal/jemalloc_preamble.h b/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/internal/jemalloc_preamble.h
new file mode 100644
index 00000000000..c150785fb4a
--- /dev/null
+++ b/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/internal/jemalloc_preamble.h
@@ -0,0 +1,194 @@
+#ifndef JEMALLOC_PREAMBLE_H
+#define JEMALLOC_PREAMBLE_H
+
+#include "jemalloc_internal_defs.h"
+#include "jemalloc/internal/jemalloc_internal_decls.h"
+
+#ifdef JEMALLOC_UTRACE
+#include
+#endif
+
+#define JEMALLOC_NO_DEMANGLE
+#ifdef JEMALLOC_JET
+# undef JEMALLOC_IS_MALLOC
+# define JEMALLOC_N(n) jet_##n
+# include "jemalloc/internal/public_namespace.h"
+# define JEMALLOC_NO_RENAME
+# include "jemalloc/jemalloc.h"
+# undef JEMALLOC_NO_RENAME
+#else
+# define JEMALLOC_N(n) je_##n
+# include "jemalloc/jemalloc.h"
+#endif
+
+#if (defined(JEMALLOC_OSATOMIC) || defined(JEMALLOC_OSSPIN))
+#include
+#endif
+
+#ifdef JEMALLOC_ZONE
+#include
+#include
+#include
+#endif
+
+#include "jemalloc/internal/jemalloc_internal_macros.h"
+
+/*
+ * Note that the ordering matters here; the hook itself is name-mangled. We
+ * want the inclusion of hooks to happen early, so that we hook as much as
+ * possible.
+ */
+#ifndef JEMALLOC_NO_PRIVATE_NAMESPACE
+# ifndef JEMALLOC_JET
+# include "jemalloc/internal/private_namespace.h"
+# else
+# include "jemalloc/internal/private_namespace_jet.h"
+# endif
+#endif
+#include "jemalloc/internal/test_hooks.h"
+
+#ifdef JEMALLOC_DEFINE_MADVISE_FREE
+# define JEMALLOC_MADV_FREE 8
+#endif
+
+static const bool config_debug =
+#ifdef JEMALLOC_DEBUG
+ true
+#else
+ false
+#endif
+ ;
+static const bool have_dss =
+#ifdef JEMALLOC_DSS
+ true
+#else
+ false
+#endif
+ ;
+static const bool have_madvise_huge =
+#ifdef JEMALLOC_HAVE_MADVISE_HUGE
+ true
+#else
+ false
+#endif
+ ;
+static const bool config_fill =
+#ifdef JEMALLOC_FILL
+ true
+#else
+ false
+#endif
+ ;
+static const bool config_lazy_lock =
+#ifdef JEMALLOC_LAZY_LOCK
+ true
+#else
+ false
+#endif
+ ;
+static const char * const config_malloc_conf = JEMALLOC_CONFIG_MALLOC_CONF;
+static const bool config_prof =
+#ifdef JEMALLOC_PROF
+ true
+#else
+ false
+#endif
+ ;
+static const bool config_prof_libgcc =
+#ifdef JEMALLOC_PROF_LIBGCC
+ true
+#else
+ false
+#endif
+ ;
+static const bool config_prof_libunwind =
+#ifdef JEMALLOC_PROF_LIBUNWIND
+ true
+#else
+ false
+#endif
+ ;
+static const bool maps_coalesce =
+#ifdef JEMALLOC_MAPS_COALESCE
+ true
+#else
+ false
+#endif
+ ;
+static const bool config_stats =
+#ifdef JEMALLOC_STATS
+ true
+#else
+ false
+#endif
+ ;
+static const bool config_tls =
+#ifdef JEMALLOC_TLS
+ true
+#else
+ false
+#endif
+ ;
+static const bool config_utrace =
+#ifdef JEMALLOC_UTRACE
+ true
+#else
+ false
+#endif
+ ;
+static const bool config_xmalloc =
+#ifdef JEMALLOC_XMALLOC
+ true
+#else
+ false
+#endif
+ ;
+static const bool config_cache_oblivious =
+#ifdef JEMALLOC_CACHE_OBLIVIOUS
+ true
+#else
+ false
+#endif
+ ;
+/*
+ * Undocumented, for jemalloc development use only at the moment. See the note
+ * in jemalloc/internal/log.h.
+ */
+static const bool config_log =
+#ifdef JEMALLOC_LOG
+ true
+#else
+ false
+#endif
+ ;
+#ifdef JEMALLOC_HAVE_SCHED_GETCPU
+/* Currently percpu_arena depends on sched_getcpu. */
+#define JEMALLOC_PERCPU_ARENA
+#endif
+static const bool have_percpu_arena =
+#ifdef JEMALLOC_PERCPU_ARENA
+ true
+#else
+ false
+#endif
+ ;
+/*
+ * Undocumented, and not recommended; the application should take full
+ * responsibility for tracking provenance.
+ */
+static const bool force_ivsalloc =
+#ifdef JEMALLOC_FORCE_IVSALLOC
+ true
+#else
+ false
+#endif
+ ;
+static const bool have_background_thread =
+#ifdef JEMALLOC_BACKGROUND_THREAD
+ true
+#else
+ false
+#endif
+ ;
+
+#endif /* JEMALLOC_PREAMBLE_H */
diff --git a/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/jemalloc_defs.h b/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/jemalloc_defs.h
new file mode 100644
index 00000000000..d1389237a77
--- /dev/null
+++ b/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/jemalloc_defs.h
@@ -0,0 +1,43 @@
+/* include/jemalloc/jemalloc_defs.h. Generated from jemalloc_defs.h.in by configure. */
+/* Defined if __attribute__((...)) syntax is supported. */
+#define JEMALLOC_HAVE_ATTR
+
+/* Defined if alloc_size attribute is supported. */
+#define JEMALLOC_HAVE_ATTR_ALLOC_SIZE
+
+/* Defined if format(printf, ...) attribute is supported. */
+#define JEMALLOC_HAVE_ATTR_FORMAT_PRINTF
+
+/*
+ * Define overrides for non-standard allocator-related functions if they are
+ * present on the system.
+ */
+#define JEMALLOC_OVERRIDE_MEMALIGN
+#define JEMALLOC_OVERRIDE_VALLOC
+
+/*
+ * At least Linux omits the "const" in:
+ *
+ * size_t malloc_usable_size(const void *ptr);
+ *
+ * Match the operating system's prototype.
+ */
+#define JEMALLOC_USABLE_SIZE_CONST
+
+/*
+ * If defined, specify throw() for the public function prototypes when compiling
+ * with C++. The only justification for this is to match the prototypes that
+ * glibc defines.
+ */
+#define JEMALLOC_USE_CXX_THROW
+
+#ifdef _MSC_VER
+# ifdef _WIN64
+# define LG_SIZEOF_PTR_WIN 3
+# else
+# define LG_SIZEOF_PTR_WIN 2
+# endif
+#endif
+
+/* sizeof(void *) == 2^LG_SIZEOF_PTR. */
+#define LG_SIZEOF_PTR 3
diff --git a/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/jemalloc_macros.h b/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/jemalloc_macros.h
new file mode 100644
index 00000000000..7432f1cda53
--- /dev/null
+++ b/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/jemalloc_macros.h
@@ -0,0 +1,122 @@
+#include
+#include
+#include
+#include
+#include
+
+#define JEMALLOC_VERSION "5.1.0-56-g41b7372eadee941b9164751b8d4963f915d3ceae"
+#define JEMALLOC_VERSION_MAJOR 5
+#define JEMALLOC_VERSION_MINOR 1
+#define JEMALLOC_VERSION_BUGFIX 0
+#define JEMALLOC_VERSION_NREV 56
+#define JEMALLOC_VERSION_GID "41b7372eadee941b9164751b8d4963f915d3ceae"
+
+#define MALLOCX_LG_ALIGN(la) ((int)(la))
+#if LG_SIZEOF_PTR == 2
+# define MALLOCX_ALIGN(a) ((int)(ffs((int)(a))-1))
+#else
+# define MALLOCX_ALIGN(a) \
+ ((int)(((size_t)(a) < (size_t)INT_MAX) ? ffs((int)(a))-1 : \
+ ffs((int)(((size_t)(a))>>32))+31))
+#endif
+#define MALLOCX_ZERO ((int)0x40)
+/*
+ * Bias tcache index bits so that 0 encodes "automatic tcache management", and 1
+ * encodes MALLOCX_TCACHE_NONE.
+ */
+#define MALLOCX_TCACHE(tc) ((int)(((tc)+2) << 8))
+#define MALLOCX_TCACHE_NONE MALLOCX_TCACHE(-1)
+/*
+ * Bias arena index bits so that 0 encodes "use an automatically chosen arena".
+ */
+#define MALLOCX_ARENA(a) ((((int)(a))+1) << 20)
+
+/*
+ * Use as arena index in "arena..{purge,decay,dss}" and
+ * "stats.arenas..*" mallctl interfaces to select all arenas. This
+ * definition is intentionally specified in raw decimal format to support
+ * cpp-based string concatenation, e.g.
+ *
+ * #define STRINGIFY_HELPER(x) #x
+ * #define STRINGIFY(x) STRINGIFY_HELPER(x)
+ *
+ * mallctl("arena." STRINGIFY(MALLCTL_ARENAS_ALL) ".purge", NULL, NULL, NULL,
+ * 0);
+ */
+#define MALLCTL_ARENAS_ALL 4096
+/*
+ * Use as arena index in "stats.arenas..*" mallctl interfaces to select
+ * destroyed arenas.
+ */
+#define MALLCTL_ARENAS_DESTROYED 4097
+
+#if defined(__cplusplus) && defined(JEMALLOC_USE_CXX_THROW)
+# define JEMALLOC_CXX_THROW throw()
+#else
+# define JEMALLOC_CXX_THROW
+#endif
+
+#if defined(_MSC_VER)
+# define JEMALLOC_ATTR(s)
+# define JEMALLOC_ALIGNED(s) __declspec(align(s))
+# define JEMALLOC_ALLOC_SIZE(s)
+# define JEMALLOC_ALLOC_SIZE2(s1, s2)
+# ifndef JEMALLOC_EXPORT
+# ifdef DLLEXPORT
+# define JEMALLOC_EXPORT __declspec(dllexport)
+# else
+# define JEMALLOC_EXPORT __declspec(dllimport)
+# endif
+# endif
+# define JEMALLOC_FORMAT_PRINTF(s, i)
+# define JEMALLOC_NOINLINE __declspec(noinline)
+# ifdef __cplusplus
+# define JEMALLOC_NOTHROW __declspec(nothrow)
+# else
+# define JEMALLOC_NOTHROW
+# endif
+# define JEMALLOC_SECTION(s) __declspec(allocate(s))
+# define JEMALLOC_RESTRICT_RETURN __declspec(restrict)
+# if _MSC_VER >= 1900 && !defined(__EDG__)
+# define JEMALLOC_ALLOCATOR __declspec(allocator)
+# else
+# define JEMALLOC_ALLOCATOR
+# endif
+#elif defined(JEMALLOC_HAVE_ATTR)
+# define JEMALLOC_ATTR(s) __attribute__((s))
+# define JEMALLOC_ALIGNED(s) JEMALLOC_ATTR(aligned(s))
+# ifdef JEMALLOC_HAVE_ATTR_ALLOC_SIZE
+# define JEMALLOC_ALLOC_SIZE(s) JEMALLOC_ATTR(alloc_size(s))
+# define JEMALLOC_ALLOC_SIZE2(s1, s2) JEMALLOC_ATTR(alloc_size(s1, s2))
+# else
+# define JEMALLOC_ALLOC_SIZE(s)
+# define JEMALLOC_ALLOC_SIZE2(s1, s2)
+# endif
+# ifndef JEMALLOC_EXPORT
+# define JEMALLOC_EXPORT JEMALLOC_ATTR(visibility("default"))
+# endif
+# ifdef JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF
+# define JEMALLOC_FORMAT_PRINTF(s, i) JEMALLOC_ATTR(format(gnu_printf, s, i))
+# elif defined(JEMALLOC_HAVE_ATTR_FORMAT_PRINTF)
+# define JEMALLOC_FORMAT_PRINTF(s, i) JEMALLOC_ATTR(format(printf, s, i))
+# else
+# define JEMALLOC_FORMAT_PRINTF(s, i)
+# endif
+# define JEMALLOC_NOINLINE JEMALLOC_ATTR(noinline)
+# define JEMALLOC_NOTHROW JEMALLOC_ATTR(nothrow)
+# define JEMALLOC_SECTION(s) JEMALLOC_ATTR(section(s))
+# define JEMALLOC_RESTRICT_RETURN
+# define JEMALLOC_ALLOCATOR
+#else
+# define JEMALLOC_ATTR(s)
+# define JEMALLOC_ALIGNED(s)
+# define JEMALLOC_ALLOC_SIZE(s)
+# define JEMALLOC_ALLOC_SIZE2(s1, s2)
+# define JEMALLOC_EXPORT
+# define JEMALLOC_FORMAT_PRINTF(s, i)
+# define JEMALLOC_NOINLINE
+# define JEMALLOC_NOTHROW
+# define JEMALLOC_SECTION(s)
+# define JEMALLOC_RESTRICT_RETURN
+# define JEMALLOC_ALLOCATOR
+#endif
diff --git a/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/jemalloc_protos.h b/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/jemalloc_protos.h
new file mode 100644
index 00000000000..ff025e30fa7
--- /dev/null
+++ b/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/jemalloc_protos.h
@@ -0,0 +1,66 @@
+/*
+ * The je_ prefix on the following public symbol declarations is an artifact
+ * of namespace management, and should be omitted in application code unless
+ * JEMALLOC_NO_DEMANGLE is defined (see jemalloc_mangle.h).
+ */
+extern JEMALLOC_EXPORT const char *je_malloc_conf;
+extern JEMALLOC_EXPORT void (*je_malloc_message)(void *cbopaque,
+ const char *s);
+
+JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
+ void JEMALLOC_NOTHROW *je_malloc(size_t size)
+ JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1);
+JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
+ void JEMALLOC_NOTHROW *je_calloc(size_t num, size_t size)
+ JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2);
+JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_posix_memalign(void **memptr,
+ size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(nonnull(1));
+JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
+ void JEMALLOC_NOTHROW *je_aligned_alloc(size_t alignment,
+ size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc)
+ JEMALLOC_ALLOC_SIZE(2);
+JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
+ void JEMALLOC_NOTHROW *je_realloc(void *ptr, size_t size)
+ JEMALLOC_CXX_THROW JEMALLOC_ALLOC_SIZE(2);
+JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_free(void *ptr)
+ JEMALLOC_CXX_THROW;
+
+JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
+ void JEMALLOC_NOTHROW *je_mallocx(size_t size, int flags)
+ JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1);
+JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
+ void JEMALLOC_NOTHROW *je_rallocx(void *ptr, size_t size,
+ int flags) JEMALLOC_ALLOC_SIZE(2);
+JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_xallocx(void *ptr, size_t size,
+ size_t extra, int flags);
+JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_sallocx(const void *ptr,
+ int flags) JEMALLOC_ATTR(pure);
+JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_dallocx(void *ptr, int flags);
+JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_sdallocx(void *ptr, size_t size,
+ int flags);
+JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_nallocx(size_t size, int flags)
+ JEMALLOC_ATTR(pure);
+
+JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctl(const char *name,
+ void *oldp, size_t *oldlenp, void *newp, size_t newlen);
+JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctlnametomib(const char *name,
+ size_t *mibp, size_t *miblenp);
+JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctlbymib(const size_t *mib,
+ size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
+JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_malloc_stats_print(
+ void (*write_cb)(void *, const char *), void *je_cbopaque,
+ const char *opts);
+JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_malloc_usable_size(
+ JEMALLOC_USABLE_SIZE_CONST void *ptr) JEMALLOC_CXX_THROW;
+
+#ifdef JEMALLOC_OVERRIDE_MEMALIGN
+JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
+ void JEMALLOC_NOTHROW *je_memalign(size_t alignment, size_t size)
+ JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc);
+#endif
+
+#ifdef JEMALLOC_OVERRIDE_VALLOC
+JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
+ void JEMALLOC_NOTHROW *je_valloc(size_t size) JEMALLOC_CXX_THROW
+ JEMALLOC_ATTR(malloc);
+#endif
diff --git a/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/jemalloc_typedefs.h b/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/jemalloc_typedefs.h
new file mode 100644
index 00000000000..1a58874306e
--- /dev/null
+++ b/contrib/jemalloc-cmake/include_linux_x86_64/jemalloc/jemalloc_typedefs.h
@@ -0,0 +1,77 @@
+typedef struct extent_hooks_s extent_hooks_t;
+
+/*
+ * void *
+ * extent_alloc(extent_hooks_t *extent_hooks, void *new_addr, size_t size,
+ * size_t alignment, bool *zero, bool *commit, unsigned arena_ind);
+ */
+typedef void *(extent_alloc_t)(extent_hooks_t *, void *, size_t, size_t, bool *,
+ bool *, unsigned);
+
+/*
+ * bool
+ * extent_dalloc(extent_hooks_t *extent_hooks, void *addr, size_t size,
+ * bool committed, unsigned arena_ind);
+ */
+typedef bool (extent_dalloc_t)(extent_hooks_t *, void *, size_t, bool,
+ unsigned);
+
+/*
+ * void
+ * extent_destroy(extent_hooks_t *extent_hooks, void *addr, size_t size,
+ * bool committed, unsigned arena_ind);
+ */
+typedef void (extent_destroy_t)(extent_hooks_t *, void *, size_t, bool,
+ unsigned);
+
+/*
+ * bool
+ * extent_commit(extent_hooks_t *extent_hooks, void *addr, size_t size,
+ * size_t offset, size_t length, unsigned arena_ind);
+ */
+typedef bool (extent_commit_t)(extent_hooks_t *, void *, size_t, size_t, size_t,
+ unsigned);
+
+/*
+ * bool
+ * extent_decommit(extent_hooks_t *extent_hooks, void *addr, size_t size,
+ * size_t offset, size_t length, unsigned arena_ind);
+ */
+typedef bool (extent_decommit_t)(extent_hooks_t *, void *, size_t, size_t,
+ size_t, unsigned);
+
+/*
+ * bool
+ * extent_purge(extent_hooks_t *extent_hooks, void *addr, size_t size,
+ * size_t offset, size_t length, unsigned arena_ind);
+ */
+typedef bool (extent_purge_t)(extent_hooks_t *, void *, size_t, size_t, size_t,
+ unsigned);
+
+/*
+ * bool
+ * extent_split(extent_hooks_t *extent_hooks, void *addr, size_t size,
+ * size_t size_a, size_t size_b, bool committed, unsigned arena_ind);
+ */
+typedef bool (extent_split_t)(extent_hooks_t *, void *, size_t, size_t, size_t,
+ bool, unsigned);
+
+/*
+ * bool
+ * extent_merge(extent_hooks_t *extent_hooks, void *addr_a, size_t size_a,
+ * void *addr_b, size_t size_b, bool committed, unsigned arena_ind);
+ */
+typedef bool (extent_merge_t)(extent_hooks_t *, void *, size_t, void *, size_t,
+ bool, unsigned);
+
+struct extent_hooks_s {
+ extent_alloc_t *alloc;
+ extent_dalloc_t *dalloc;
+ extent_destroy_t *destroy;
+ extent_commit_t *commit;
+ extent_decommit_t *decommit;
+ extent_purge_t *purge_lazy;
+ extent_purge_t *purge_forced;
+ extent_split_t *split;
+ extent_merge_t *merge;
+};
diff --git a/contrib/mariadb-connector-c b/contrib/mariadb-connector-c
new file mode 160000
index 00000000000..a0fd36cc5a5
--- /dev/null
+++ b/contrib/mariadb-connector-c
@@ -0,0 +1 @@
+Subproject commit a0fd36cc5a5313414a5a2ebe9322577a29b4782a
diff --git a/contrib/mariadb-connector-c-cmake/CMakeLists.txt b/contrib/mariadb-connector-c-cmake/CMakeLists.txt
new file mode 100644
index 00000000000..4c1184b3edb
--- /dev/null
+++ b/contrib/mariadb-connector-c-cmake/CMakeLists.txt
@@ -0,0 +1,66 @@
+set(MARIADB_CLIENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/contrib/mariadb-connector-c)
+set(MARIADB_CLIENT_BINARY_DIR ${CMAKE_BINARY_DIR}/contrib/mariadb-connector-c)
+
+set(SRCS
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/bmove_upp.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/get_password.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_alloc.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_array.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_charset.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_compress.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_context.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_default.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_dtoa.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_errmsg.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_hash.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_init.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_io.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_list.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_ll2str.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_loaddata.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_net.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_password.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_pvio.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/mariadb_async.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/mariadb_charset.c
+#${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/mariadb_dyncol.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/mariadb_lib.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/mariadb_stmt.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_sha1.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_stmt_codec.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_string.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_time.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/ma_tls.c
+#${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/secure/gnutls.c
+#${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/secure/ma_schannel.c
+${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/secure/openssl.c
+#${MARIADB_CLIENT_SOURCE_DIR}/libmariadb/secure/schannel.c
+#${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/auth_gssapi_client.c
+#${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/dialog.c
+#${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/gssapi_client.c
+#${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/gssapi_errmsg.c
+${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/mariadb_cleartext.c
+${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/my_auth.c
+${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/old_password.c
+${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/sha256_pw.c
+#${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/sspi_client.c
+#${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/sspi_errmsg.c
+${MARIADB_CLIENT_SOURCE_DIR}/plugins/connection/aurora.c
+${MARIADB_CLIENT_SOURCE_DIR}/plugins/connection/replication.c
+#${MARIADB_CLIENT_SOURCE_DIR}/plugins/io/remote_io.c
+#${MARIADB_CLIENT_SOURCE_DIR}/plugins/pvio/pvio_npipe.c
+#${MARIADB_CLIENT_SOURCE_DIR}/plugins/pvio/pvio_shmem.c
+${MARIADB_CLIENT_SOURCE_DIR}/plugins/pvio/pvio_socket.c
+#${MARIADB_CLIENT_SOURCE_DIR}/plugins/trace/trace_example.c
+${CMAKE_CURRENT_SOURCE_DIR}/linux_x86_64/libmariadb/ma_client_plugin.c
+)
+
+add_library(mysqlclient STATIC ${SRCS})
+
+target_link_libraries(mysqlclient ${OPENSSL_LIBRARIES})
+
+target_include_directories(mysqlclient PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/linux_x86_64/include)
+target_include_directories(mysqlclient PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/common/include)
+target_include_directories(mysqlclient PUBLIC ${MARIADB_CLIENT_SOURCE_DIR}/include)
+
+target_compile_definitions(mysqlclient PRIVATE -D THREAD -D HAVE_OPENSSL -D HAVE_TLS)
diff --git a/contrib/mariadb-connector-c-cmake/common/include/mysql/mysql.h b/contrib/mariadb-connector-c-cmake/common/include/mysql/mysql.h
new file mode 100644
index 00000000000..741c7ba03c9
--- /dev/null
+++ b/contrib/mariadb-connector-c-cmake/common/include/mysql/mysql.h
@@ -0,0 +1 @@
+#include
diff --git a/contrib/mariadb-connector-c-cmake/common/include/mysql/mysqld_error.h b/contrib/mariadb-connector-c-cmake/common/include/mysql/mysqld_error.h
new file mode 100644
index 00000000000..95d26eef163
--- /dev/null
+++ b/contrib/mariadb-connector-c-cmake/common/include/mysql/mysqld_error.h
@@ -0,0 +1 @@
+#include
diff --git a/contrib/mariadb-connector-c-cmake/linux_x86_64/include/config.h b/contrib/mariadb-connector-c-cmake/linux_x86_64/include/config.h
new file mode 100644
index 00000000000..90c42c97df6
--- /dev/null
+++ b/contrib/mariadb-connector-c-cmake/linux_x86_64/include/config.h
@@ -0,0 +1,269 @@
+
+/*
+ * Include file constants (processed in LibmysqlIncludeFiles.txt 1
+ */
+#define HAVE_ALLOCA_H 1
+/* #undef HAVE_BIGENDIAN */
+#define HAVE_SETLOCALE 1
+#define HAVE_NL_LANGINFO 1
+#define HAVE_ARPA_INET_H 1
+#define HAVE_CRYPT_H 1
+#define HAVE_DIRENT_H 1
+#define HAVE_DLFCN_H 1
+#define HAVE_EXECINFO_H 1
+#define HAVE_FCNTL_H 1
+#define HAVE_FENV_H 1
+#define HAVE_FLOAT_H 1
+/* #undef HAVE_FPU_CONTROL_H */
+#define HAVE_GRP_H 1
+/* #undef HAVE_IEEEFP_H */
+#define HAVE_LIMITS_H 1
+#define HAVE_MALLOC_H 1
+#define HAVE_MEMORY_H 1
+#define HAVE_NETINET_IN_H 1
+#define HAVE_PATHS_H 1
+#define HAVE_PWD_H 1
+#define HAVE_SCHED_H 1
+/* #undef HAVE_SELECT_H */
+#define HAVE_STDDEF_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STRING_H 1
+#define HAVE_STRINGS_H 1
+/* #undef HAVE_SYNCH_H */
+/* #undef HAVE_SYS_FPU_H */
+#define HAVE_SYS_IOCTL_H 1
+#define HAVE_SYS_IPC_H 1
+#define HAVE_SYS_MMAN_H 1
+#define HAVE_SYS_PRCTL_H 1
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_SYS_SHM_H 1
+#define HAVE_SYS_SOCKET_H 1
+#define HAVE_SYS_STAT_H 1
+/* #undef HAVE_SYS_STREAM_H */
+#define HAVE_SYS_TIMEB_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_SYS_UN_H 1
+/* #undef HAVE_SYSENT_H */
+#define HAVE_TERMIO_H 1
+#define HAVE_TERMIOS_H 1
+#define HAVE_UNISTD_H 1
+#define HAVE_UTIME_H 1
+#define HAVE_UCONTEXT_H 1
+
+/*
+ * function definitions - processed in LibmysqlFunctions.txt
+ */
+#define HAVE_ACCESS 1
+/* #undef HAVE_AIOWAIT */
+#define HAVE_ALARM 1
+/* #undef HAVE_ALLOCA */
+#define HAVE_BCMP 1
+/* #undef HAVE_BFILL */
+/* #undef HAVE_BMOVE */
+#define HAVE_BZERO 1
+#define HAVE_CLOCK_GETTIME 1
+/* #undef HAVE_COMPRESS */
+/* #undef HAVE_CRYPT */
+#define HAVE_DLERROR 1
+#define HAVE_DLOPEN 1
+#define HAVE_FCHMOD 1
+#define HAVE_FCNTL 1
+/* #undef HAVE_FCONVERT */
+#define HAVE_FDATASYNC 1
+#define HAVE_FESETROUND 1
+#define HAVE_FINITE 1
+#define HAVE_FSEEKO 1
+#define HAVE_FSYNC 1
+#define HAVE_GETADDRINFO 1
+#define HAVE_GETCWD 1
+#define HAVE_GETHOSTBYADDR_R 1
+#define HAVE_GETHOSTBYNAME_R 1
+/* #undef HAVE_GETHRTIME */
+#define HAVE_GETNAMEINFO 1
+#define HAVE_GETPAGESIZE 1
+#define HAVE_GETPASS 1
+/* #undef HAVE_GETPASSPHRASE */
+#define HAVE_GETPWNAM 1
+#define HAVE_GETPWUID 1
+#define HAVE_GETRLIMIT 1
+#define HAVE_GETRUSAGE 1
+#define HAVE_GETWD 1
+#define HAVE_GMTIME_R 1
+#define HAVE_INITGROUPS 1
+#define HAVE_LDIV 1
+#define HAVE_LOCALTIME_R 1
+#define HAVE_LOG2 1
+#define HAVE_LONGJMP 1
+#define HAVE_LSTAT 1
+#define HAVE_MADVISE 1
+#define HAVE_MALLINFO 1
+#define HAVE_MEMALIGN 1
+#define HAVE_MEMCPY 1
+#define HAVE_MEMMOVE 1
+#define HAVE_MKSTEMP 1
+#define HAVE_MLOCK 1
+#define HAVE_MLOCKALL 1
+#define HAVE_MMAP 1
+#define HAVE_MMAP64 1
+#define HAVE_PERROR 1
+#define HAVE_POLL 1
+#define HAVE_PREAD 1
+/* #undef HAVE_PTHREAD_ATTR_CREATE */
+#define HAVE_PTHREAD_ATTR_GETSTACKSIZE 1
+/* #undef HAVE_PTHREAD_ATTR_SETPRIO */
+#define HAVE_PTHREAD_ATTR_SETSCHEDPARAM 1
+#define HAVE_PTHREAD_ATTR_SETSCOPE 1
+#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
+/* #undef HAVE_PTHREAD_CONDATTR_CREATE */
+/* #undef HAVE_PTHREAD_INIT */
+#define HAVE_PTHREAD_KEY_DELETE 1
+#define HAVE_PTHREAD_KILL 1
+#define HAVE_PTHREAD_RWLOCK_RDLOCK 1
+/* #undef HAVE_PTHREAD_SETPRIO_NP */
+#define HAVE_PTHREAD_SETSCHEDPARAM 1
+#define HAVE_PTHREAD_SIGMASK 1
+/* #undef HAVE_PTHREAD_THREADMASK */
+/* #undef HAVE_PTHREAD_YIELD_NP */
+#define HAVE_READDIR_R 1
+#define HAVE_READLINK 1
+#define HAVE_REALPATH 1
+#define HAVE_RENAME 1
+#define HAVE_SCHED_YIELD 1
+#define HAVE_SELECT 1
+/* #undef HAVE_SETFD */
+/* #undef HAVE_SETFILEPOINTER */
+#define HAVE_SIGNAL 1
+#define HAVE_SIGACTION 1
+/* #undef HAVE_SIGTHREADMASK */
+#define HAVE_SIGWAIT 1
+#define HAVE_SLEEP 1
+#define HAVE_SNPRINTF 1
+/* #undef HAVE_SQLITE */
+#define HAVE_STPCPY 1
+#define HAVE_STRERROR 1
+/* #undef HAVE_STRLCPY */
+#define HAVE_STRNLEN 1
+#define HAVE_STRPBRK 1
+#define HAVE_STRSEP 1
+#define HAVE_STRSTR 1
+#define HAVE_STRTOK_R 1
+#define HAVE_STRTOL 1
+#define HAVE_STRTOLL 1
+#define HAVE_STRTOUL 1
+#define HAVE_STRTOULL 1
+/* #undef HAVE_TELL */
+/* #undef HAVE_THR_SETCONCURRENCY */
+/* #undef HAVE_THR_YIELD */
+#define HAVE_VASPRINTF 1
+#define HAVE_VSNPRINTF 1
+
+/*
+ * types and sizes
+ */
+/* Types we may use */
+#define SIZEOF_CHAR 1
+#if defined(SIZEOF_CHAR)
+# define HAVE_CHAR 1
+#endif
+
+#define SIZEOF_CHARP 8
+#if defined(SIZEOF_CHARP)
+# define HAVE_CHARP 1
+#endif
+
+#define SIZEOF_SHORT 2
+#if defined(SIZEOF_SHORT)
+# define HAVE_SHORT 1
+#endif
+
+#define SIZEOF_INT 4
+#if defined(SIZEOF_INT)
+# define HAVE_INT 1
+#endif
+
+#define SIZEOF_LONG 8
+#if defined(SIZEOF_LONG)
+# define HAVE_LONG 1
+#endif
+
+#define SIZEOF_LONG_LONG 8
+#if defined(SIZEOF_LONG_LONG)
+# define HAVE_LONG_LONG 1
+#endif
+
+
+#define SIZEOF_SIGSET_T 128
+#if defined(SIZEOF_SIGSET_T)
+# define HAVE_SIGSET_T 1
+#endif
+
+#define SIZEOF_SIZE_T 8
+#if defined(SIZEOF_SIZE_T)
+# define HAVE_SIZE_T 1
+#endif
+
+/* #undef SIZEOF_UCHAR */
+#if defined(SIZEOF_UCHAR)
+# define HAVE_UCHAR 1
+#endif
+
+#define SIZEOF_UINT 4
+#if defined(SIZEOF_UINT)
+# define HAVE_UINT 1
+#endif
+
+#define SIZEOF_ULONG 8
+#if defined(SIZEOF_ULONG)
+# define HAVE_ULONG 1
+#endif
+
+/* #undef SIZEOF_INT8 */
+#if defined(SIZEOF_INT8)
+# define HAVE_INT8 1
+#endif
+/* #undef SIZEOF_UINT8 */
+#if defined(SIZEOF_UINT8)
+# define HAVE_UINT8 1
+#endif
+
+/* #undef SIZEOF_INT16 */
+#if defined(SIZEOF_INT16)
+# define HAVE_INT16 1
+#endif
+/* #undef SIZEOF_UINT16 */
+#if defined(SIZEOF_UINT16)
+# define HAVE_UINT16 1
+#endif
+
+/* #undef SIZEOF_INT32 */
+#if defined(SIZEOF_INT32)
+# define HAVE_INT32 1
+#endif
+/* #undef SIZEOF_UINT32 */
+#if defined(SIZEOF_UINT32)
+# define HAVE_UINT32 1
+#endif
+/* #undef SIZEOF_U_INT32_T */
+#if defined(SIZEOF_U_INT32_T)
+# define HAVE_U_INT32_T 1
+#endif
+
+/* #undef SIZEOF_INT64 */
+#if defined(SIZEOF_INT64)
+# define HAVE_INT64 1
+#endif
+/* #undef SIZEOF_UINT64 */
+#if defined(SIZEOF_UINT64)
+# define HAVE_UINT64 1
+#endif
+
+/* #undef SIZEOF_SOCKLEN_T */
+#if defined(SIZEOF_SOCKLEN_T)
+# define HAVE_SOCKLEN_T 1
+#endif
+
+#define SOCKET_SIZE_TYPE socklen_t
+
+#define MARIADB_DEFAULT_CHARSET "latin1"
+
diff --git a/contrib/mariadb-connector-c-cmake/linux_x86_64/include/ma_config.h b/contrib/mariadb-connector-c-cmake/linux_x86_64/include/ma_config.h
new file mode 100644
index 00000000000..90c42c97df6
--- /dev/null
+++ b/contrib/mariadb-connector-c-cmake/linux_x86_64/include/ma_config.h
@@ -0,0 +1,269 @@
+
+/*
+ * Include file constants (processed in LibmysqlIncludeFiles.txt 1
+ */
+#define HAVE_ALLOCA_H 1
+/* #undef HAVE_BIGENDIAN */
+#define HAVE_SETLOCALE 1
+#define HAVE_NL_LANGINFO 1
+#define HAVE_ARPA_INET_H 1
+#define HAVE_CRYPT_H 1
+#define HAVE_DIRENT_H 1
+#define HAVE_DLFCN_H 1
+#define HAVE_EXECINFO_H 1
+#define HAVE_FCNTL_H 1
+#define HAVE_FENV_H 1
+#define HAVE_FLOAT_H 1
+/* #undef HAVE_FPU_CONTROL_H */
+#define HAVE_GRP_H 1
+/* #undef HAVE_IEEEFP_H */
+#define HAVE_LIMITS_H 1
+#define HAVE_MALLOC_H 1
+#define HAVE_MEMORY_H 1
+#define HAVE_NETINET_IN_H 1
+#define HAVE_PATHS_H 1
+#define HAVE_PWD_H 1
+#define HAVE_SCHED_H 1
+/* #undef HAVE_SELECT_H */
+#define HAVE_STDDEF_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STRING_H 1
+#define HAVE_STRINGS_H 1
+/* #undef HAVE_SYNCH_H */
+/* #undef HAVE_SYS_FPU_H */
+#define HAVE_SYS_IOCTL_H 1
+#define HAVE_SYS_IPC_H 1
+#define HAVE_SYS_MMAN_H 1
+#define HAVE_SYS_PRCTL_H 1
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_SYS_SHM_H 1
+#define HAVE_SYS_SOCKET_H 1
+#define HAVE_SYS_STAT_H 1
+/* #undef HAVE_SYS_STREAM_H */
+#define HAVE_SYS_TIMEB_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_SYS_UN_H 1
+/* #undef HAVE_SYSENT_H */
+#define HAVE_TERMIO_H 1
+#define HAVE_TERMIOS_H 1
+#define HAVE_UNISTD_H 1
+#define HAVE_UTIME_H 1
+#define HAVE_UCONTEXT_H 1
+
+/*
+ * function definitions - processed in LibmysqlFunctions.txt
+ */
+#define HAVE_ACCESS 1
+/* #undef HAVE_AIOWAIT */
+#define HAVE_ALARM 1
+/* #undef HAVE_ALLOCA */
+#define HAVE_BCMP 1
+/* #undef HAVE_BFILL */
+/* #undef HAVE_BMOVE */
+#define HAVE_BZERO 1
+#define HAVE_CLOCK_GETTIME 1
+/* #undef HAVE_COMPRESS */
+/* #undef HAVE_CRYPT */
+#define HAVE_DLERROR 1
+#define HAVE_DLOPEN 1
+#define HAVE_FCHMOD 1
+#define HAVE_FCNTL 1
+/* #undef HAVE_FCONVERT */
+#define HAVE_FDATASYNC 1
+#define HAVE_FESETROUND 1
+#define HAVE_FINITE 1
+#define HAVE_FSEEKO 1
+#define HAVE_FSYNC 1
+#define HAVE_GETADDRINFO 1
+#define HAVE_GETCWD 1
+#define HAVE_GETHOSTBYADDR_R 1
+#define HAVE_GETHOSTBYNAME_R 1
+/* #undef HAVE_GETHRTIME */
+#define HAVE_GETNAMEINFO 1
+#define HAVE_GETPAGESIZE 1
+#define HAVE_GETPASS 1
+/* #undef HAVE_GETPASSPHRASE */
+#define HAVE_GETPWNAM 1
+#define HAVE_GETPWUID 1
+#define HAVE_GETRLIMIT 1
+#define HAVE_GETRUSAGE 1
+#define HAVE_GETWD 1
+#define HAVE_GMTIME_R 1
+#define HAVE_INITGROUPS 1
+#define HAVE_LDIV 1
+#define HAVE_LOCALTIME_R 1
+#define HAVE_LOG2 1
+#define HAVE_LONGJMP 1
+#define HAVE_LSTAT 1
+#define HAVE_MADVISE 1
+#define HAVE_MALLINFO 1
+#define HAVE_MEMALIGN 1
+#define HAVE_MEMCPY 1
+#define HAVE_MEMMOVE 1
+#define HAVE_MKSTEMP 1
+#define HAVE_MLOCK 1
+#define HAVE_MLOCKALL 1
+#define HAVE_MMAP 1
+#define HAVE_MMAP64 1
+#define HAVE_PERROR 1
+#define HAVE_POLL 1
+#define HAVE_PREAD 1
+/* #undef HAVE_PTHREAD_ATTR_CREATE */
+#define HAVE_PTHREAD_ATTR_GETSTACKSIZE 1
+/* #undef HAVE_PTHREAD_ATTR_SETPRIO */
+#define HAVE_PTHREAD_ATTR_SETSCHEDPARAM 1
+#define HAVE_PTHREAD_ATTR_SETSCOPE 1
+#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
+/* #undef HAVE_PTHREAD_CONDATTR_CREATE */
+/* #undef HAVE_PTHREAD_INIT */
+#define HAVE_PTHREAD_KEY_DELETE 1
+#define HAVE_PTHREAD_KILL 1
+#define HAVE_PTHREAD_RWLOCK_RDLOCK 1
+/* #undef HAVE_PTHREAD_SETPRIO_NP */
+#define HAVE_PTHREAD_SETSCHEDPARAM 1
+#define HAVE_PTHREAD_SIGMASK 1
+/* #undef HAVE_PTHREAD_THREADMASK */
+/* #undef HAVE_PTHREAD_YIELD_NP */
+#define HAVE_READDIR_R 1
+#define HAVE_READLINK 1
+#define HAVE_REALPATH 1
+#define HAVE_RENAME 1
+#define HAVE_SCHED_YIELD 1
+#define HAVE_SELECT 1
+/* #undef HAVE_SETFD */
+/* #undef HAVE_SETFILEPOINTER */
+#define HAVE_SIGNAL 1
+#define HAVE_SIGACTION 1
+/* #undef HAVE_SIGTHREADMASK */
+#define HAVE_SIGWAIT 1
+#define HAVE_SLEEP 1
+#define HAVE_SNPRINTF 1
+/* #undef HAVE_SQLITE */
+#define HAVE_STPCPY 1
+#define HAVE_STRERROR 1
+/* #undef HAVE_STRLCPY */
+#define HAVE_STRNLEN 1
+#define HAVE_STRPBRK 1
+#define HAVE_STRSEP 1
+#define HAVE_STRSTR 1
+#define HAVE_STRTOK_R 1
+#define HAVE_STRTOL 1
+#define HAVE_STRTOLL 1
+#define HAVE_STRTOUL 1
+#define HAVE_STRTOULL 1
+/* #undef HAVE_TELL */
+/* #undef HAVE_THR_SETCONCURRENCY */
+/* #undef HAVE_THR_YIELD */
+#define HAVE_VASPRINTF 1
+#define HAVE_VSNPRINTF 1
+
+/*
+ * types and sizes
+ */
+/* Types we may use */
+#define SIZEOF_CHAR 1
+#if defined(SIZEOF_CHAR)
+# define HAVE_CHAR 1
+#endif
+
+#define SIZEOF_CHARP 8
+#if defined(SIZEOF_CHARP)
+# define HAVE_CHARP 1
+#endif
+
+#define SIZEOF_SHORT 2
+#if defined(SIZEOF_SHORT)
+# define HAVE_SHORT 1
+#endif
+
+#define SIZEOF_INT 4
+#if defined(SIZEOF_INT)
+# define HAVE_INT 1
+#endif
+
+#define SIZEOF_LONG 8
+#if defined(SIZEOF_LONG)
+# define HAVE_LONG 1
+#endif
+
+#define SIZEOF_LONG_LONG 8
+#if defined(SIZEOF_LONG_LONG)
+# define HAVE_LONG_LONG 1
+#endif
+
+
+#define SIZEOF_SIGSET_T 128
+#if defined(SIZEOF_SIGSET_T)
+# define HAVE_SIGSET_T 1
+#endif
+
+#define SIZEOF_SIZE_T 8
+#if defined(SIZEOF_SIZE_T)
+# define HAVE_SIZE_T 1
+#endif
+
+/* #undef SIZEOF_UCHAR */
+#if defined(SIZEOF_UCHAR)
+# define HAVE_UCHAR 1
+#endif
+
+#define SIZEOF_UINT 4
+#if defined(SIZEOF_UINT)
+# define HAVE_UINT 1
+#endif
+
+#define SIZEOF_ULONG 8
+#if defined(SIZEOF_ULONG)
+# define HAVE_ULONG 1
+#endif
+
+/* #undef SIZEOF_INT8 */
+#if defined(SIZEOF_INT8)
+# define HAVE_INT8 1
+#endif
+/* #undef SIZEOF_UINT8 */
+#if defined(SIZEOF_UINT8)
+# define HAVE_UINT8 1
+#endif
+
+/* #undef SIZEOF_INT16 */
+#if defined(SIZEOF_INT16)
+# define HAVE_INT16 1
+#endif
+/* #undef SIZEOF_UINT16 */
+#if defined(SIZEOF_UINT16)
+# define HAVE_UINT16 1
+#endif
+
+/* #undef SIZEOF_INT32 */
+#if defined(SIZEOF_INT32)
+# define HAVE_INT32 1
+#endif
+/* #undef SIZEOF_UINT32 */
+#if defined(SIZEOF_UINT32)
+# define HAVE_UINT32 1
+#endif
+/* #undef SIZEOF_U_INT32_T */
+#if defined(SIZEOF_U_INT32_T)
+# define HAVE_U_INT32_T 1
+#endif
+
+/* #undef SIZEOF_INT64 */
+#if defined(SIZEOF_INT64)
+# define HAVE_INT64 1
+#endif
+/* #undef SIZEOF_UINT64 */
+#if defined(SIZEOF_UINT64)
+# define HAVE_UINT64 1
+#endif
+
+/* #undef SIZEOF_SOCKLEN_T */
+#if defined(SIZEOF_SOCKLEN_T)
+# define HAVE_SOCKLEN_T 1
+#endif
+
+#define SOCKET_SIZE_TYPE socklen_t
+
+#define MARIADB_DEFAULT_CHARSET "latin1"
+
diff --git a/contrib/mariadb-connector-c-cmake/linux_x86_64/include/mariadb_version.h b/contrib/mariadb-connector-c-cmake/linux_x86_64/include/mariadb_version.h
new file mode 100644
index 00000000000..821a7f8add2
--- /dev/null
+++ b/contrib/mariadb-connector-c-cmake/linux_x86_64/include/mariadb_version.h
@@ -0,0 +1,36 @@
+/* Copyright Abandoned 1996, 1999, 2001 MySQL AB
+ This file is public domain and comes with NO WARRANTY of any kind */
+
+/* Version numbers for protocol & mysqld */
+
+#ifndef _mariadb_version_h_
+#define _mariadb_version_h_
+
+#ifdef _CUSTOMCONFIG_
+#include
+#else
+#define PROTOCOL_VERSION 10
+#define MARIADB_CLIENT_VERSION_STR "10.3.6"
+#define MARIADB_BASE_VERSION "mariadb-10.3"
+#define MARIADB_VERSION_ID 100306
+#define MYSQL_VERSION_ID 100306
+#define MARIADB_PORT 3306
+#define MARIADB_UNIX_ADDR "/var/run/mysqld/mysqld.sock"
+#define MYSQL_CONFIG_NAME "my"
+
+#define MARIADB_PACKAGE_VERSION "3.0.6"
+#define MARIADB_PACKAGE_VERSION_ID 30006
+#define MARIADB_SYSTEM_TYPE "Linux"
+#define MARIADB_MACHINE_TYPE "x86_64"
+#define MARIADB_PLUGINDIR "lib/mariadb/plugin"
+
+/* mysqld compile time options */
+#ifndef MYSQL_CHARSET
+#define MYSQL_CHARSET ""
+#endif
+#endif
+
+/* Source information */
+#define CC_SOURCE_REVISION "a0fd36cc5a5313414a5a2ebe9322577a29b4782a"
+
+#endif /* _mariadb_version_h_ */
diff --git a/contrib/mariadb-connector-c-cmake/linux_x86_64/libmariadb/ma_client_plugin.c b/contrib/mariadb-connector-c-cmake/linux_x86_64/libmariadb/ma_client_plugin.c
new file mode 100644
index 00000000000..b7fdcdbcb85
--- /dev/null
+++ b/contrib/mariadb-connector-c-cmake/linux_x86_64/libmariadb/ma_client_plugin.c
@@ -0,0 +1,499 @@
+/* Copyright (C) 2010 - 2012 Sergei Golubchik and Monty Program Ab
+ 2015-2016 MariaDB Corporation AB
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not see
+ or write to the Free Software Foundation, Inc.,
+ 51 Franklin St., Fifth Floor, Boston, MA 02110, USA */
+
+/**
+ @file
+
+ Support code for the client side (libmariadb) plugins
+
+ Client plugins are somewhat different from server plugins, they are simpler.
+
+ They do not need to be installed or in any way explicitly loaded on the
+ client, they are loaded automatically on demand.
+ One client plugin per shared object, soname *must* match the plugin name.
+
+ There is no reference counting and no unloading either.
+*/
+
+#if _MSC_VER
+/* Silence warnings about variable 'unused' being used. */
+#define FORCE_INIT_OF_VARS 1
+#endif
+
+#include
+#include
+#include
+#include
+#include
+
+#include "errmsg.h"
+#include
+
+struct st_client_plugin_int {
+ struct st_client_plugin_int *next;
+ void *dlhandle;
+ struct st_mysql_client_plugin *plugin;
+};
+
+static my_bool initialized= 0;
+static MA_MEM_ROOT mem_root;
+
+static uint valid_plugins[][2]= {
+ {MYSQL_CLIENT_AUTHENTICATION_PLUGIN, MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION},
+ {MARIADB_CLIENT_PVIO_PLUGIN, MARIADB_CLIENT_PVIO_PLUGIN_INTERFACE_VERSION},
+ {MARIADB_CLIENT_TRACE_PLUGIN, MARIADB_CLIENT_TRACE_PLUGIN_INTERFACE_VERSION},
+ {MARIADB_CLIENT_CONNECTION_PLUGIN, MARIADB_CLIENT_CONNECTION_PLUGIN_INTERFACE_VERSION},
+ {0, 0}
+};
+
+/*
+ Loaded plugins are stored in a linked list.
+ The list is append-only, the elements are added to the head (like in a stack).
+ The elements are added under a mutex, but the list can be read and traversed
+ without any mutex because once an element is added to the list, it stays
+ there. The main purpose of a mutex is to prevent two threads from
+ loading the same plugin twice in parallel.
+*/
+
+
+struct st_client_plugin_int *plugin_list[MYSQL_CLIENT_MAX_PLUGINS + MARIADB_CLIENT_MAX_PLUGINS];
+#ifdef THREAD
+static pthread_mutex_t LOCK_load_client_plugin;
+#endif
+
+ extern struct st_mysql_client_plugin mysql_native_password_client_plugin;
+ extern struct st_mysql_client_plugin mysql_old_password_client_plugin;
+ extern struct st_mysql_client_plugin pvio_socket_client_plugin;
+
+
+struct st_mysql_client_plugin *mysql_client_builtins[]=
+{
+ (struct st_mysql_client_plugin *)&mysql_native_password_client_plugin,
+ (struct st_mysql_client_plugin *)&mysql_old_password_client_plugin,
+ (struct st_mysql_client_plugin *)&pvio_socket_client_plugin,
+
+ 0
+};
+
+
+static int is_not_initialized(MYSQL *mysql, const char *name)
+{
+ if (initialized)
+ return 0;
+
+ my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD,
+ SQLSTATE_UNKNOWN, ER(CR_AUTH_PLUGIN_CANNOT_LOAD),
+ name, "not initialized");
+ return 1;
+}
+
+static int get_plugin_nr(uint type)
+{
+ uint i= 0;
+ for(; valid_plugins[i][1]; i++)
+ if (valid_plugins[i][0] == type)
+ return i;
+ return -1;
+}
+
+static const char *check_plugin_version(struct st_mysql_client_plugin *plugin, unsigned int version)
+{
+ if (plugin->interface_version < version ||
+ (plugin->interface_version >> 8) > (version >> 8))
+ return "Incompatible client plugin interface";
+ return 0;
+}
+
+/**
+ finds a plugin in the list
+
+ @param name plugin name to search for
+ @param type plugin type
+
+ @note this does NOT necessarily need a mutex, take care!
+
+ @retval a pointer to a found plugin or 0
+*/
+static struct st_mysql_client_plugin *find_plugin(const char *name, int type)
+{
+ struct st_client_plugin_int *p;
+ int plugin_nr= get_plugin_nr(type);
+
+ DBUG_ASSERT(initialized);
+ if (plugin_nr == -1)
+ return 0;
+
+ if (!name)
+ return plugin_list[plugin_nr]->plugin;
+
+ for (p= plugin_list[plugin_nr]; p; p= p->next)
+ {
+ if (strcmp(p->plugin->name, name) == 0)
+ return p->plugin;
+ }
+ return NULL;
+}
+
+
+/**
+ verifies the plugin and adds it to the list
+
+ @param mysql MYSQL structure (for error reporting)
+ @param plugin plugin to install
+ @param dlhandle a handle to the shared object (returned by dlopen)
+ or 0 if the plugin was not dynamically loaded
+ @param argc number of arguments in the 'va_list args'
+ @param args arguments passed to the plugin initialization function
+
+ @retval a pointer to an installed plugin or 0
+*/
+
+static struct st_mysql_client_plugin *
+add_plugin(MYSQL *mysql, struct st_mysql_client_plugin *plugin, void *dlhandle,
+ int argc, va_list args)
+{
+ const char *errmsg;
+ struct st_client_plugin_int plugin_int, *p;
+ char errbuf[1024];
+ int plugin_nr;
+
+ DBUG_ASSERT(initialized);
+
+ plugin_int.plugin= plugin;
+ plugin_int.dlhandle= dlhandle;
+
+ if ((plugin_nr= get_plugin_nr(plugin->type)) == -1)
+ {
+ errmsg= "Unknown client plugin type";
+ goto err1;
+ }
+ if ((errmsg= check_plugin_version(plugin, valid_plugins[plugin_nr][1])))
+ goto err1;
+
+ /* Call the plugin initialization function, if any */
+ if (plugin->init && plugin->init(errbuf, sizeof(errbuf), argc, args))
+ {
+ errmsg= errbuf;
+ goto err1;
+ }
+
+ p= (struct st_client_plugin_int *)
+ ma_memdup_root(&mem_root, (char *)&plugin_int, sizeof(plugin_int));
+
+ if (!p)
+ {
+ errmsg= "Out of memory";
+ goto err2;
+ }
+
+#ifdef THREAD
+ safe_mutex_assert_owner(&LOCK_load_client_plugin);
+#endif
+
+ p->next= plugin_list[plugin_nr];
+ plugin_list[plugin_nr]= p;
+
+ return plugin;
+
+err2:
+ if (plugin->deinit)
+ plugin->deinit();
+err1:
+ my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, SQLSTATE_UNKNOWN,
+ ER(CR_AUTH_PLUGIN_CANNOT_LOAD), plugin->name, errmsg);
+ if (dlhandle)
+ (void)dlclose(dlhandle);
+ return NULL;
+}
+
+
+/**
+ Loads plugins which are specified in the environment variable
+ LIBMYSQL_PLUGINS.
+
+ Multiple plugins must be separated by semicolon. This function doesn't
+ return or log an error.
+
+ The function is be called by mysql_client_plugin_init
+
+ @todo
+ Support extended syntax, passing parameters to plugins, for example
+ LIBMYSQL_PLUGINS="plugin1(param1,param2);plugin2;..."
+ or
+ LIBMYSQL_PLUGINS="plugin1=int:param1,str:param2;plugin2;..."
+*/
+
+static void load_env_plugins(MYSQL *mysql)
+{
+ char *plugs, *free_env, *s= getenv("LIBMYSQL_PLUGINS");
+
+ if (ma_check_env_str(s))
+ return;
+
+ free_env= strdup(s);
+ plugs= s= free_env;
+
+ do {
+ if ((s= strchr(plugs, ';')))
+ *s= '\0';
+ mysql_load_plugin(mysql, plugs, -1, 0);
+ plugs= s + 1;
+ } while (s);
+
+ free(free_env);
+}
+
+/********** extern functions to be used by libmariadb *********************/
+
+/**
+ Initializes the client plugin layer.
+
+ This function must be called before any other client plugin function.
+
+ @retval 0 successful
+ @retval != 0 error occurred
+*/
+
+int mysql_client_plugin_init()
+{
+ MYSQL mysql;
+ struct st_mysql_client_plugin **builtin;
+ va_list unused;
+ LINT_INIT_STRUCT(unused);
+
+ if (initialized)
+ return 0;
+
+ memset(&mysql, 0, sizeof(mysql)); /* dummy mysql for set_mysql_extended_error */
+
+ pthread_mutex_init(&LOCK_load_client_plugin, MY_MUTEX_INIT_SLOW);
+ ma_init_alloc_root(&mem_root, 128, 128);
+
+ memset(&plugin_list, 0, sizeof(plugin_list));
+
+ initialized= 1;
+
+ pthread_mutex_lock(&LOCK_load_client_plugin);
+ for (builtin= mysql_client_builtins; *builtin; builtin++)
+ add_plugin(&mysql, *builtin, 0, 0, unused);
+
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+
+ load_env_plugins(&mysql);
+
+ return 0;
+}
+
+
+/**
+ Deinitializes the client plugin layer.
+
+ Unloades all client plugins and frees any associated resources.
+*/
+
+void mysql_client_plugin_deinit()
+{
+ int i;
+ struct st_client_plugin_int *p;
+
+ if (!initialized)
+ return;
+
+ for (i=0; i < MYSQL_CLIENT_MAX_PLUGINS; i++)
+ for (p= plugin_list[i]; p; p= p->next)
+ {
+ if (p->plugin->deinit)
+ p->plugin->deinit();
+ if (p->dlhandle)
+ (void)dlclose(p->dlhandle);
+ }
+
+ memset(&plugin_list, 0, sizeof(plugin_list));
+ initialized= 0;
+ ma_free_root(&mem_root, MYF(0));
+ pthread_mutex_destroy(&LOCK_load_client_plugin);
+}
+
+/************* public facing functions, for client consumption *********/
+
+/* see for a full description */
+struct st_mysql_client_plugin * STDCALL
+mysql_client_register_plugin(MYSQL *mysql,
+ struct st_mysql_client_plugin *plugin)
+{
+ va_list unused;
+ LINT_INIT_STRUCT(unused);
+
+ if (is_not_initialized(mysql, plugin->name))
+ return NULL;
+
+ pthread_mutex_lock(&LOCK_load_client_plugin);
+
+ /* make sure the plugin wasn't loaded meanwhile */
+ if (find_plugin(plugin->name, plugin->type))
+ {
+ my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD,
+ SQLSTATE_UNKNOWN, ER(CR_AUTH_PLUGIN_CANNOT_LOAD),
+ plugin->name, "it is already loaded");
+ plugin= NULL;
+ }
+ else
+ plugin= add_plugin(mysql, plugin, 0, 0, unused);
+
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+ return plugin;
+}
+
+
+/* see for a full description */
+struct st_mysql_client_plugin * STDCALL
+mysql_load_plugin_v(MYSQL *mysql, const char *name, int type,
+ int argc, va_list args)
+{
+ const char *errmsg;
+#ifdef _WIN32
+ char errbuf[1024];
+#endif
+ char dlpath[FN_REFLEN+1];
+ void *sym, *dlhandle = NULL;
+ struct st_mysql_client_plugin *plugin;
+ char *env_plugin_dir= getenv("MARIADB_PLUGIN_DIR");
+
+ CLEAR_CLIENT_ERROR(mysql);
+ if (is_not_initialized(mysql, name))
+ return NULL;
+
+ pthread_mutex_lock(&LOCK_load_client_plugin);
+
+ /* make sure the plugin wasn't loaded meanwhile */
+ if (type >= 0 && find_plugin(name, type))
+ {
+ errmsg= "it is already loaded";
+ goto err;
+ }
+
+ /* Compile dll path */
+ snprintf(dlpath, sizeof(dlpath) - 1, "%s/%s%s",
+ mysql->options.extension && mysql->options.extension->plugin_dir ?
+ mysql->options.extension->plugin_dir : (env_plugin_dir) ? env_plugin_dir :
+ MARIADB_PLUGINDIR, name, SO_EXT);
+
+ /* Open new dll handle */
+ if (!(dlhandle= dlopen((const char *)dlpath, RTLD_NOW)))
+ {
+#ifdef _WIN32
+ char winmsg[255];
+ size_t len;
+ winmsg[0] = 0;
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ winmsg, 255, NULL);
+ len= strlen(winmsg);
+ while (len > 0 && (winmsg[len - 1] == '\n' || winmsg[len - 1] == '\r'))
+ len--;
+ if (len)
+ winmsg[len] = 0;
+ snprintf(errbuf, sizeof(errbuf), "%s Library path is '%s'", winmsg, dlpath);
+ errmsg= errbuf;
+#else
+ errmsg= dlerror();
+#endif
+ goto err;
+ }
+
+
+ if (!(sym= dlsym(dlhandle, plugin_declarations_sym)))
+ {
+ errmsg= "not a plugin";
+ (void)dlclose(dlhandle);
+ goto err;
+ }
+
+ plugin= (struct st_mysql_client_plugin*)sym;
+
+ if (type >=0 && type != plugin->type)
+ {
+ errmsg= "type mismatch";
+ goto err;
+ }
+
+ if (strcmp(name, plugin->name))
+ {
+ errmsg= "name mismatch";
+ goto err;
+ }
+
+ if (type < 0 && find_plugin(name, plugin->type))
+ {
+ errmsg= "it is already loaded";
+ goto err;
+ }
+
+ plugin= add_plugin(mysql, plugin, dlhandle, argc, args);
+
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+
+ return plugin;
+
+err:
+ if (dlhandle)
+ dlclose(dlhandle);
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+ my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, SQLSTATE_UNKNOWN,
+ ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name, errmsg);
+ return NULL;
+}
+
+
+/* see for a full description */
+struct st_mysql_client_plugin * STDCALL
+mysql_load_plugin(MYSQL *mysql, const char *name, int type, int argc, ...)
+{
+ struct st_mysql_client_plugin *p;
+ va_list args;
+ va_start(args, argc);
+ p= mysql_load_plugin_v(mysql, name, type, argc, args);
+ va_end(args);
+ return p;
+}
+
+/* see for a full description */
+struct st_mysql_client_plugin * STDCALL
+mysql_client_find_plugin(MYSQL *mysql, const char *name, int type)
+{
+ struct st_mysql_client_plugin *p;
+ int plugin_nr= get_plugin_nr(type);
+
+ if (is_not_initialized(mysql, name))
+ return NULL;
+
+ if (plugin_nr == -1)
+ {
+ my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, SQLSTATE_UNKNOWN,
+ ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name, "invalid type");
+ }
+
+ if ((p= find_plugin(name, type)))
+ return p;
+
+ /* not found, load it */
+ return mysql_load_plugin(mysql, name, type, 0);
+}
+
diff --git a/contrib/murmurhash/CMakeLists.txt b/contrib/murmurhash/CMakeLists.txt
new file mode 100644
index 00000000000..c5e467a2d6d
--- /dev/null
+++ b/contrib/murmurhash/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_library(murmurhash
+ src/murmurhash2.cpp
+ src/murmurhash3.cpp
+ include/murmurhash2.h
+ include/murmurhash3.h)
+
+target_include_directories (murmurhash PUBLIC include)
diff --git a/contrib/murmurhash/LICENSE b/contrib/murmurhash/LICENSE
new file mode 100644
index 00000000000..f6cdede60b8
--- /dev/null
+++ b/contrib/murmurhash/LICENSE
@@ -0,0 +1 @@
+MurmurHash was written by Austin Appleby, and is placed in the publicdomain. The author hereby disclaims copyright to this source code.
diff --git a/contrib/murmurhash/README b/contrib/murmurhash/README
new file mode 100644
index 00000000000..5428d30b26d
--- /dev/null
+++ b/contrib/murmurhash/README
@@ -0,0 +1,6 @@
+Original URL: https://github.com/aappleby/smhasher
+
+version:
+commit 61a0530f28277f2e850bfc39600ce61d02b518de
+author aappleby@gmail.com
+date 2016-01-09T06:07:17Z
diff --git a/contrib/murmurhash/include/murmurhash2.h b/contrib/murmurhash/include/murmurhash2.h
new file mode 100644
index 00000000000..e95cf2a4d85
--- /dev/null
+++ b/contrib/murmurhash/include/murmurhash2.h
@@ -0,0 +1,35 @@
+//-----------------------------------------------------------------------------
+// MurmurHash2 was written by Austin Appleby, and is placed in the public
+// domain. The author hereby disclaims copyright to this source code.
+
+#ifndef _MURMURHASH2_H_
+#define _MURMURHASH2_H_
+
+//-----------------------------------------------------------------------------
+// Platform-specific functions and macros
+
+// Microsoft Visual Studio
+
+#if defined(_MSC_VER) && (_MSC_VER < 1600)
+
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+typedef unsigned __int64 uint64_t;
+
+// Other compilers
+
+#else // defined(_MSC_VER)
+
+#include
+
+#endif // !defined(_MSC_VER)
+
+uint32_t MurmurHash2 (const void * key, int len, uint32_t seed);
+uint64_t MurmurHash64A (const void * key, int len, uint64_t seed);
+uint64_t MurmurHash64B (const void * key, int len, uint64_t seed);
+uint32_t MurmurHash2A (const void * key, int len, uint32_t seed);
+uint32_t MurmurHashNeutral2 (const void * key, int len, uint32_t seed);
+uint32_t MurmurHashAligned2 (const void * key, int len, uint32_t seed);
+
+#endif // _MURMURHASH2_H_
+
diff --git a/contrib/murmurhash/include/murmurhash3.h b/contrib/murmurhash/include/murmurhash3.h
new file mode 100644
index 00000000000..e1c6d34976c
--- /dev/null
+++ b/contrib/murmurhash/include/murmurhash3.h
@@ -0,0 +1,37 @@
+//-----------------------------------------------------------------------------
+// MurmurHash3 was written by Austin Appleby, and is placed in the public
+// domain. The author hereby disclaims copyright to this source code.
+
+#ifndef _MURMURHASH3_H_
+#define _MURMURHASH3_H_
+
+//-----------------------------------------------------------------------------
+// Platform-specific functions and macros
+
+// Microsoft Visual Studio
+
+#if defined(_MSC_VER) && (_MSC_VER < 1600)
+
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+typedef unsigned __int64 uint64_t;
+
+// Other compilers
+
+#else // defined(_MSC_VER)
+
+#include
+
+#endif // !defined(_MSC_VER)
+
+//-----------------------------------------------------------------------------
+
+void MurmurHash3_x86_32 ( const void * key, int len, uint32_t seed, void * out );
+
+void MurmurHash3_x86_128 ( const void * key, int len, uint32_t seed, void * out );
+
+void MurmurHash3_x64_128 ( const void * key, int len, uint32_t seed, void * out );
+
+//-----------------------------------------------------------------------------
+
+#endif // _MURMURHASH3_H_
diff --git a/contrib/murmurhash/src/murmurhash2.cpp b/contrib/murmurhash/src/murmurhash2.cpp
new file mode 100644
index 00000000000..8a41ba02d98
--- /dev/null
+++ b/contrib/murmurhash/src/murmurhash2.cpp
@@ -0,0 +1,421 @@
+// MurmurHash2 was written by Austin Appleby, and is placed in the public
+// domain. The author hereby disclaims copyright to this source code.
+
+// Note - This code makes a few assumptions about how your machine behaves -
+
+// 1. We can read a 4-byte value from any address without crashing
+// 2. sizeof(int) == 4
+
+// And it has a few limitations -
+
+// 1. It will not work incrementally.
+// 2. It will not produce the same results on little-endian and big-endian
+// machines.
+
+#include "murmurhash2.h"
+
+// Platform-specific functions and macros
+// Microsoft Visual Studio
+
+#if defined(_MSC_VER)
+
+#define BIG_CONSTANT(x) (x)
+
+// Other compilers
+
+#else // defined(_MSC_VER)
+
+#define BIG_CONSTANT(x) (x##LLU)
+
+#endif // !defined(_MSC_VER)
+
+
+uint32_t MurmurHash2(const void * key, int len, uint32_t seed)
+{
+ // 'm' and 'r' are mixing constants generated offline.
+ // They're not really 'magic', they just happen to work well.
+
+ const uint32_t m = 0x5bd1e995;
+ const int r = 24;
+
+ // Initialize the hash to a 'random' value
+
+ uint32_t h = seed ^ len;
+
+ // Mix 4 bytes at a time into the hash
+
+ const unsigned char * data = reinterpret_cast(key);
+
+ while (len >= 4)
+ {
+ uint32_t k = *reinterpret_cast(data);
+ k *= m;
+ k ^= k >> r;
+ k *= m;
+
+ h *= m;
+ h ^= k;
+
+ data += 4;
+ len -= 4;
+ }
+
+ // Handle the last few bytes of the input array
+
+ switch (len)
+ {
+ case 3: h ^= data[2] << 16;
+ case 2: h ^= data[1] << 8;
+ case 1: h ^= data[0];
+ h *= m;
+ };
+
+ // Do a few final mixes of the hash to ensure the last few
+ // bytes are well-incorporated.
+
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+
+ return h;
+}
+
+// MurmurHash2, 64-bit versions, by Austin Appleby
+
+// The same caveats as 32-bit MurmurHash2 apply here - beware of alignment
+// and endian-ness issues if used across multiple platforms.
+
+// 64-bit hash for 64-bit platforms
+
+uint64_t MurmurHash64A(const void * key, int len, uint64_t seed)
+{
+ const uint64_t m = BIG_CONSTANT(0xc6a4a7935bd1e995);
+ const int r = 47;
+
+ uint64_t h = seed ^ (len * m);
+
+ const uint64_t * data = reinterpret_cast(key);
+ const uint64_t * end = data + (len/8);
+
+ while (data != end)
+ {
+ uint64_t k = *data++;
+
+ k *= m;
+ k ^= k >> r;
+ k *= m;
+
+ h ^= k;
+ h *= m;
+ }
+
+ const unsigned char * data2 = reinterpret_cast(data);
+
+ switch (len & 7)
+ {
+ case 7: h ^= static_cast(data2[6]) << 48;
+ case 6: h ^= static_cast(data2[5]) << 40;
+ case 5: h ^= static_cast(data2[4]) << 32;
+ case 4: h ^= static_cast(data2[3]) << 24;
+ case 3: h ^= static_cast(data2[2]) << 16;
+ case 2: h ^= static_cast(data2[1]) << 8;
+ case 1: h ^= static_cast(data2[0]);
+ h *= m;
+ };
+
+ h ^= h >> r;
+ h *= m;
+ h ^= h >> r;
+
+ return h;
+}
+
+
+// 64-bit hash for 32-bit platforms
+
+uint64_t MurmurHash64B(const void * key, int len, uint64_t seed)
+{
+ const uint32_t m = 0x5bd1e995;
+ const int r = 24;
+
+ uint32_t h1 = static_cast(seed) ^ len;
+ uint32_t h2 = static_cast(seed >> 32);
+
+ const uint32_t * data = reinterpret_cast(key);
+
+ while (len >= 8)
+ {
+ uint32_t k1 = *data++;
+ k1 *= m; k1 ^= k1 >> r; k1 *= m;
+ h1 *= m; h1 ^= k1;
+ len -= 4;
+
+ uint32_t k2 = *data++;
+ k2 *= m; k2 ^= k2 >> r; k2 *= m;
+ h2 *= m; h2 ^= k2;
+ len -= 4;
+ }
+
+ if (len >= 4)
+ {
+ uint32_t k1 = *data++;
+ k1 *= m; k1 ^= k1 >> r; k1 *= m;
+ h1 *= m; h1 ^= k1;
+ len -= 4;
+ }
+
+ switch (len)
+ {
+ case 3: h2 ^= reinterpret_cast(data)[2] << 16;
+ case 2: h2 ^= reinterpret_cast(data)[1] << 8;
+ case 1: h2 ^= reinterpret_cast(data)[0];
+ h2 *= m;
+ };
+
+ h1 ^= h2 >> 18; h1 *= m;
+ h2 ^= h1 >> 22; h2 *= m;
+ h1 ^= h2 >> 17; h1 *= m;
+ h2 ^= h1 >> 19; h2 *= m;
+
+ uint64_t h = h1;
+
+ h = (h << 32) | h2;
+
+ return h;
+}
+
+// MurmurHash2A, by Austin Appleby
+
+// This is a variant of MurmurHash2 modified to use the Merkle-Damgard
+// construction. Bulk speed should be identical to Murmur2, small-key speed
+// will be 10%-20% slower due to the added overhead at the end of the hash.
+
+// This variant fixes a minor issue where null keys were more likely to
+// collide with each other than expected, and also makes the function
+// more amenable to incremental implementations.
+
+#define mmix(h,k) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
+
+uint32_t MurmurHash2A(const void * key, int len, uint32_t seed)
+{
+ const uint32_t m = 0x5bd1e995;
+ const int r = 24;
+ uint32_t l = len;
+
+ const unsigned char * data = reinterpret_cast(key);
+
+ uint32_t h = seed;
+
+ while (len >= 4)
+ {
+ uint32_t k = *reinterpret_cast(data);
+ mmix(h,k);
+ data += 4;
+ len -= 4;
+ }
+
+ uint32_t t = 0;
+
+ switch (len)
+ {
+ case 3: t ^= data[2] << 16;
+ case 2: t ^= data[1] << 8;
+ case 1: t ^= data[0];
+ };
+
+ mmix(h,t);
+ mmix(h,l);
+
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+
+ return h;
+}
+
+// MurmurHashNeutral2, by Austin Appleby
+
+// Same as MurmurHash2, but endian- and alignment-neutral.
+// Half the speed though, alas.
+
+uint32_t MurmurHashNeutral2(const void * key, int len, uint32_t seed)
+{
+ const uint32_t m = 0x5bd1e995;
+ const int r = 24;
+
+ uint32_t h = seed ^ len;
+
+ const unsigned char * data = reinterpret_cast(key);
+
+ while (len >= 4)
+ {
+ uint32_t k;
+
+ k = data[0];
+ k |= data[1] << 8;
+ k |= data[2] << 16;
+ k |= data[3] << 24;
+
+ k *= m;
+ k ^= k >> r;
+ k *= m;
+
+ h *= m;
+ h ^= k;
+
+ data += 4;
+ len -= 4;
+ }
+
+ switch (len)
+ {
+ case 3: h ^= data[2] << 16;
+ case 2: h ^= data[1] << 8;
+ case 1: h ^= data[0];
+ h *= m;
+ };
+
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+
+ return h;
+}
+
+//-----------------------------------------------------------------------------
+// MurmurHashAligned2, by Austin Appleby
+
+// Same algorithm as MurmurHash2, but only does aligned reads - should be safer
+// on certain platforms.
+
+// Performance will be lower than MurmurHash2
+
+#define MIX(h,k,m) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
+
+
+uint32_t MurmurHashAligned2(const void * key, int len, uint32_t seed)
+{
+ const uint32_t m = 0x5bd1e995;
+ const int r = 24;
+
+ const unsigned char * data = reinterpret_cast(key);
+
+ uint32_t h = seed ^ len;
+
+ int align = reinterpret_cast(data) & 3;
+
+ if (align && (len >= 4))
+ {
+ // Pre-load the temp registers
+
+ uint32_t t = 0, d = 0;
+
+ switch (align)
+ {
+ case 1: t |= data[2] << 16;
+ case 2: t |= data[1] << 8;
+ case 3: t |= data[0];
+ }
+
+ t <<= (8 * align);
+
+ data += 4-align;
+ len -= 4-align;
+
+ int sl = 8 * (4-align);
+ int sr = 8 * align;
+
+ // Mix
+
+ while (len >= 4)
+ {
+ d = *(reinterpret_cast(data));
+ t = (t >> sr) | (d << sl);
+
+ uint32_t k = t;
+
+ MIX(h,k,m);
+
+ t = d;
+
+ data += 4;
+ len -= 4;
+ }
+
+ // Handle leftover data in temp registers
+
+ d = 0;
+
+ if (len >= align)
+ {
+ switch (align)
+ {
+ case 3: d |= data[2] << 16;
+ case 2: d |= data[1] << 8;
+ case 1: d |= data[0];
+ }
+
+ uint32_t k = (t >> sr) | (d << sl);
+ MIX(h,k,m);
+
+ data += align;
+ len -= align;
+
+ //----------
+ // Handle tail bytes
+
+ switch (len)
+ {
+ case 3: h ^= data[2] << 16;
+ case 2: h ^= data[1] << 8;
+ case 1: h ^= data[0];
+ h *= m;
+ };
+ }
+ else
+ {
+ switch (len)
+ {
+ case 3: d |= data[2] << 16;
+ case 2: d |= data[1] << 8;
+ case 1: d |= data[0];
+ case 0: h ^= (t >> sr) | (d << sl);
+ h *= m;
+ }
+ }
+
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+
+ return h;
+ }
+ else
+ {
+ while (len >= 4)
+ {
+ uint32_t k = *reinterpret_cast(data);
+
+ MIX(h,k,m);
+
+ data += 4;
+ len -= 4;
+ }
+
+ // Handle tail bytes
+
+ switch (len)
+ {
+ case 3: h ^= data[2] << 16;
+ case 2: h ^= data[1] << 8;
+ case 1: h ^= data[0];
+ h *= m;
+ };
+
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+
+ return h;
+ }
+}
\ No newline at end of file
diff --git a/contrib/murmurhash/src/murmurhash3.cpp b/contrib/murmurhash/src/murmurhash3.cpp
new file mode 100644
index 00000000000..2831bf5c73b
--- /dev/null
+++ b/contrib/murmurhash/src/murmurhash3.cpp
@@ -0,0 +1,331 @@
+// MurmurHash3 was written by Austin Appleby, and is placed in the public
+// domain. The author hereby disclaims copyright to this source code.
+
+// Note - The x86 and x64 versions do _not_ produce the same results, as the
+// algorithms are optimized for their respective platforms. You can still
+// compile and run any of them on any platform, but your performance with the
+// non-native version will be less than optimal.
+
+#include "murmurhash3.h"
+
+//-----------------------------------------------------------------------------
+// Platform-specific functions and macros
+
+// Microsoft Visual Studio
+
+#if defined(_MSC_VER)
+
+#define FORCE_INLINE __forceinline
+
+#include
+
+#define ROTL32(x,y) _rotl(x,y)
+#define ROTL64(x,y) _rotl64(x,y)
+
+#define BIG_CONSTANT(x) (x)
+
+// Other compilers
+
+#else // defined(_MSC_VER)
+
+#define FORCE_INLINE inline __attribute__((always_inline))
+
+inline uint32_t rotl32 ( uint32_t x, int8_t r )
+{
+ return (x << r) | (x >> (32 - r));
+}
+
+inline uint64_t rotl64 ( uint64_t x, int8_t r )
+{
+ return (x << r) | (x >> (64 - r));
+}
+
+#define ROTL32(x,y) rotl32(x,y)
+#define ROTL64(x,y) rotl64(x,y)
+
+#define BIG_CONSTANT(x) (x##LLU)
+
+#endif // !defined(_MSC_VER)
+
+//-----------------------------------------------------------------------------
+// Block read - if your platform needs to do endian-swapping or can only
+// handle aligned reads, do the conversion here
+
+FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i )
+{
+ return p[i];
+}
+
+FORCE_INLINE uint64_t getblock64 ( const uint64_t * p, int i )
+{
+ return p[i];
+}
+
+//-----------------------------------------------------------------------------
+// Finalization mix - force all bits of a hash block to avalanche
+
+FORCE_INLINE uint32_t fmix32 ( uint32_t h )
+{
+ h ^= h >> 16;
+ h *= 0x85ebca6b;
+ h ^= h >> 13;
+ h *= 0xc2b2ae35;
+ h ^= h >> 16;
+
+ return h;
+}
+
+//----------
+
+FORCE_INLINE uint64_t fmix64 ( uint64_t k )
+{
+ k ^= k >> 33;
+ k *= BIG_CONSTANT(0xff51afd7ed558ccd);
+ k ^= k >> 33;
+ k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
+ k ^= k >> 33;
+
+ return k;
+}
+
+//-----------------------------------------------------------------------------
+
+void MurmurHash3_x86_32 ( const void * key, int len,
+ uint32_t seed, void * out )
+{
+ const uint8_t * data = (const uint8_t*)key;
+ const int nblocks = len / 4;
+
+ uint32_t h1 = seed;
+
+ const uint32_t c1 = 0xcc9e2d51;
+ const uint32_t c2 = 0x1b873593;
+
+ //----------
+ // body
+
+ const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
+
+ for(int i = -nblocks; i; i++)
+ {
+ uint32_t k1 = getblock32(blocks,i);
+
+ k1 *= c1;
+ k1 = ROTL32(k1,15);
+ k1 *= c2;
+
+ h1 ^= k1;
+ h1 = ROTL32(h1,13);
+ h1 = h1*5+0xe6546b64;
+ }
+
+ //----------
+ // tail
+
+ const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
+
+ uint32_t k1 = 0;
+
+ switch(len & 3)
+ {
+ case 3: k1 ^= tail[2] << 16;
+ case 2: k1 ^= tail[1] << 8;
+ case 1: k1 ^= tail[0];
+ k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
+ };
+
+ //----------
+ // finalization
+
+ h1 ^= len;
+
+ h1 = fmix32(h1);
+
+ *(uint32_t*)out = h1;
+}
+
+//-----------------------------------------------------------------------------
+
+void MurmurHash3_x86_128 ( const void * key, const int len,
+ uint32_t seed, void * out )
+{
+ const uint8_t * data = (const uint8_t*)key;
+ const int nblocks = len / 16;
+
+ uint32_t h1 = seed;
+ uint32_t h2 = seed;
+ uint32_t h3 = seed;
+ uint32_t h4 = seed;
+
+ const uint32_t c1 = 0x239b961b;
+ const uint32_t c2 = 0xab0e9789;
+ const uint32_t c3 = 0x38b34ae5;
+ const uint32_t c4 = 0xa1e38b93;
+
+ //----------
+ // body
+
+ const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
+
+ for(int i = -nblocks; i; i++)
+ {
+ uint32_t k1 = getblock32(blocks,i*4+0);
+ uint32_t k2 = getblock32(blocks,i*4+1);
+ uint32_t k3 = getblock32(blocks,i*4+2);
+ uint32_t k4 = getblock32(blocks,i*4+3);
+
+ k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
+
+ h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;
+
+ k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
+
+ h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;
+
+ k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
+
+ h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;
+
+ k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
+
+ h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
+ }
+
+ //----------
+ // tail
+
+ const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
+
+ uint32_t k1 = 0;
+ uint32_t k2 = 0;
+ uint32_t k3 = 0;
+ uint32_t k4 = 0;
+
+ switch(len & 15)
+ {
+ case 15: k4 ^= tail[14] << 16;
+ case 14: k4 ^= tail[13] << 8;
+ case 13: k4 ^= tail[12] << 0;
+ k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
+
+ case 12: k3 ^= tail[11] << 24;
+ case 11: k3 ^= tail[10] << 16;
+ case 10: k3 ^= tail[ 9] << 8;
+ case 9: k3 ^= tail[ 8] << 0;
+ k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
+
+ case 8: k2 ^= tail[ 7] << 24;
+ case 7: k2 ^= tail[ 6] << 16;
+ case 6: k2 ^= tail[ 5] << 8;
+ case 5: k2 ^= tail[ 4] << 0;
+ k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
+
+ case 4: k1 ^= tail[ 3] << 24;
+ case 3: k1 ^= tail[ 2] << 16;
+ case 2: k1 ^= tail[ 1] << 8;
+ case 1: k1 ^= tail[ 0] << 0;
+ k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
+ };
+
+ //----------
+ // finalization
+
+ h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
+
+ h1 += h2; h1 += h3; h1 += h4;
+ h2 += h1; h3 += h1; h4 += h1;
+
+ h1 = fmix32(h1);
+ h2 = fmix32(h2);
+ h3 = fmix32(h3);
+ h4 = fmix32(h4);
+
+ h1 += h2; h1 += h3; h1 += h4;
+ h2 += h1; h3 += h1; h4 += h1;
+
+ ((uint32_t*)out)[0] = h1;
+ ((uint32_t*)out)[1] = h2;
+ ((uint32_t*)out)[2] = h3;
+ ((uint32_t*)out)[3] = h4;
+}
+
+//-----------------------------------------------------------------------------
+
+void MurmurHash3_x64_128 ( const void * key, const int len,
+ const uint32_t seed, void * out )
+{
+ const uint8_t * data = (const uint8_t*)key;
+ const int nblocks = len / 16;
+
+ uint64_t h1 = seed;
+ uint64_t h2 = seed;
+
+ const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
+ const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
+
+ //----------
+ // body
+
+ const uint64_t * blocks = (const uint64_t *)(data);
+
+ for(int i = 0; i < nblocks; i++)
+ {
+ uint64_t k1 = getblock64(blocks,i*2+0);
+ uint64_t k2 = getblock64(blocks,i*2+1);
+
+ k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
+
+ h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
+
+ k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
+
+ h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
+ }
+
+ //----------
+ // tail
+
+ const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
+
+ uint64_t k1 = 0;
+ uint64_t k2 = 0;
+
+ switch(len & 15)
+ {
+ case 15: k2 ^= ((uint64_t)tail[14]) << 48;
+ case 14: k2 ^= ((uint64_t)tail[13]) << 40;
+ case 13: k2 ^= ((uint64_t)tail[12]) << 32;
+ case 12: k2 ^= ((uint64_t)tail[11]) << 24;
+ case 11: k2 ^= ((uint64_t)tail[10]) << 16;
+ case 10: k2 ^= ((uint64_t)tail[ 9]) << 8;
+ case 9: k2 ^= ((uint64_t)tail[ 8]) << 0;
+ k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
+
+ case 8: k1 ^= ((uint64_t)tail[ 7]) << 56;
+ case 7: k1 ^= ((uint64_t)tail[ 6]) << 48;
+ case 6: k1 ^= ((uint64_t)tail[ 5]) << 40;
+ case 5: k1 ^= ((uint64_t)tail[ 4]) << 32;
+ case 4: k1 ^= ((uint64_t)tail[ 3]) << 24;
+ case 3: k1 ^= ((uint64_t)tail[ 2]) << 16;
+ case 2: k1 ^= ((uint64_t)tail[ 1]) << 8;
+ case 1: k1 ^= ((uint64_t)tail[ 0]) << 0;
+ k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
+ };
+
+ //----------
+ // finalization
+
+ h1 ^= len; h2 ^= len;
+
+ h1 += h2;
+ h2 += h1;
+
+ h1 = fmix64(h1);
+ h2 = fmix64(h2);
+
+ h1 += h2;
+ h2 += h1;
+
+ ((uint64_t*)out)[0] = h1;
+ ((uint64_t*)out)[1] = h2;
+}
diff --git a/contrib/poco b/contrib/poco
index 3a2d0a833a2..4ab45bc3bb0 160000
--- a/contrib/poco
+++ b/contrib/poco
@@ -1 +1 @@
-Subproject commit 3a2d0a833a22ef5e1164a9ada54e3253cb038904
+Subproject commit 4ab45bc3bb0d2c476ea5385ec2d398c6bfc9f089
diff --git a/contrib/re2_st/CMakeLists.txt b/contrib/re2_st/CMakeLists.txt
index cd0f97e08f3..79362f4bb56 100644
--- a/contrib/re2_st/CMakeLists.txt
+++ b/contrib/re2_st/CMakeLists.txt
@@ -16,22 +16,22 @@ target_include_directories (re2_st PRIVATE . PUBLIC ${CMAKE_CURRENT_BINARY_DIR}
file (MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/re2_st)
foreach (FILENAME filtered_re2.h re2.h set.h stringpiece.h)
- add_custom_command (OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/re2_st/${FILENAME}"
- COMMAND ${CMAKE_COMMAND} -DSOURCE_FILENAME="${RE2_SOURCE_DIR}/re2/${FILENAME}"
- -DTARGET_FILENAME="${CMAKE_CURRENT_BINARY_DIR}/re2_st/${FILENAME}"
- -P "${CMAKE_CURRENT_SOURCE_DIR}/re2_transform.cmake"
- COMMENT "Creating ${FILENAME} for re2_st library.")
- add_custom_target (transform_${FILENAME} DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/re2_st/${FILENAME}")
- add_dependencies (re2_st transform_${FILENAME})
+ add_custom_command (OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/re2_st/${FILENAME}"
+ COMMAND ${CMAKE_COMMAND} -DSOURCE_FILENAME="${RE2_SOURCE_DIR}/re2/${FILENAME}"
+ -DTARGET_FILENAME="${CMAKE_CURRENT_BINARY_DIR}/re2_st/${FILENAME}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/re2_transform.cmake"
+ COMMENT "Creating ${FILENAME} for re2_st library.")
+ add_custom_target (transform_${FILENAME} DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/re2_st/${FILENAME}")
+ add_dependencies (re2_st transform_${FILENAME})
endforeach ()
file (MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/util)
foreach (FILENAME mutex.h)
- add_custom_command (OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/util/${FILENAME}"
- COMMAND ${CMAKE_COMMAND} -DSOURCE_FILENAME="${RE2_SOURCE_DIR}/util/${FILENAME}"
- -DTARGET_FILENAME="${CMAKE_CURRENT_BINARY_DIR}/util/${FILENAME}"
- -P "${CMAKE_CURRENT_SOURCE_DIR}/re2_transform.cmake"
- COMMENT "Creating ${FILENAME} for re2_st library.")
- add_custom_target (transform_${FILENAME} DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/util/${FILENAME}")
- add_dependencies (re2_st transform_${FILENAME})
+ add_custom_command (OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/util/${FILENAME}"
+ COMMAND ${CMAKE_COMMAND} -DSOURCE_FILENAME="${RE2_SOURCE_DIR}/util/${FILENAME}"
+ -DTARGET_FILENAME="${CMAKE_CURRENT_BINARY_DIR}/util/${FILENAME}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/re2_transform.cmake"
+ COMMENT "Creating ${FILENAME} for re2_st library.")
+ add_custom_target (transform_${FILENAME} DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/util/${FILENAME}")
+ add_dependencies (re2_st transform_${FILENAME})
endforeach ()
diff --git a/contrib/ssl b/contrib/ssl
index 6fbe1c6f404..4f9a7b87451 160000
--- a/contrib/ssl
+++ b/contrib/ssl
@@ -1 +1 @@
-Subproject commit 6fbe1c6f404193989c5f6a63115d80fbe34ce2a3
+Subproject commit 4f9a7b8745184410dc0b31ba548ce21ac64edd9c
diff --git a/contrib/unixodbc b/contrib/unixodbc
new file mode 160000
index 00000000000..b0ad30f7f62
--- /dev/null
+++ b/contrib/unixodbc
@@ -0,0 +1 @@
+Subproject commit b0ad30f7f6289c12b76f04bfb9d466374bb32168
diff --git a/contrib/unixodbc-cmake/CMakeLists.txt b/contrib/unixodbc-cmake/CMakeLists.txt
new file mode 100644
index 00000000000..4f9f6b41538
--- /dev/null
+++ b/contrib/unixodbc-cmake/CMakeLists.txt
@@ -0,0 +1,288 @@
+set(ODBC_SOURCE_DIR ${CMAKE_SOURCE_DIR}/contrib/unixodbc)
+set(ODBC_BINARY_DIR ${CMAKE_BINARY_DIR}/contrib/unixodbc)
+
+
+set(SRCS
+${ODBC_SOURCE_DIR}/libltdl/lt__alloc.c
+${ODBC_SOURCE_DIR}/libltdl/lt__strl.c
+${ODBC_SOURCE_DIR}/libltdl/ltdl.c
+${ODBC_SOURCE_DIR}/libltdl/lt_dlloader.c
+${ODBC_SOURCE_DIR}/libltdl/slist.c
+${ODBC_SOURCE_DIR}/libltdl/lt_error.c
+${ODBC_SOURCE_DIR}/libltdl/loaders/dlopen.c
+${ODBC_SOURCE_DIR}/libltdl/loaders/preopen.c
+#${ODBC_SOURCE_DIR}/libltdl/lt__dirent.c
+#${ODBC_SOURCE_DIR}/libltdl/lt__argz.c
+#${ODBC_SOURCE_DIR}/libltdl/loaders/dld_link.c
+#${ODBC_SOURCE_DIR}/libltdl/loaders/load_add_on.c
+#${ODBC_SOURCE_DIR}/libltdl/loaders/shl_load.c
+#${ODBC_SOURCE_DIR}/libltdl/loaders/loadlibrary.c
+#${ODBC_SOURCE_DIR}/libltdl/loaders/dyld.c
+
+# This file is generated by 'libtool' inside libltdl directory and then removed.
+${CMAKE_CURRENT_SOURCE_DIR}/linux_x86_64/libltdl/libltdlcS.c
+)
+
+add_library(ltdl STATIC ${SRCS})
+
+target_include_directories(ltdl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/linux_x86_64/libltdl)
+target_include_directories(ltdl PUBLIC ${ODBC_SOURCE_DIR}/libltdl)
+target_include_directories(ltdl PUBLIC ${ODBC_SOURCE_DIR}/libltdl/libltdl)
+
+target_compile_definitions(ltdl PRIVATE -DHAVE_CONFIG_H -DLTDL -DLTDLOPEN=libltdlc)
+
+target_compile_options(ltdl PRIVATE -Wno-constant-logical-operand -Wno-unknown-warning-option -O2)
+
+
+set(SRCS
+${ODBC_SOURCE_DIR}/DriverManager/__attribute.c
+${ODBC_SOURCE_DIR}/DriverManager/__connection.c
+${ODBC_SOURCE_DIR}/DriverManager/__handles.c
+${ODBC_SOURCE_DIR}/DriverManager/__info.c
+${ODBC_SOURCE_DIR}/DriverManager/__stats.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLAllocConnect.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLAllocEnv.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLAllocHandle.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLAllocHandleStd.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLAllocStmt.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLBindCol.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLBindParam.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLBindParameter.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLBrowseConnect.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLBrowseConnectW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLBulkOperations.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLCancel.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLCancelHandle.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLCloseCursor.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLColAttribute.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLColAttributes.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLColAttributesW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLColAttributeW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLColumnPrivileges.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLColumnPrivilegesW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLColumns.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLColumnsW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLConnect.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLConnectW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLCopyDesc.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLDataSources.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLDataSourcesW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLDescribeCol.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLDescribeColW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLDescribeParam.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLDisconnect.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLDriverConnect.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLDriverConnectW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLDrivers.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLDriversW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLEndTran.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLError.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLErrorW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLExecDirect.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLExecDirectW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLExecute.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLExtendedFetch.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLFetch.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLFetchScroll.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLForeignKeys.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLForeignKeysW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLFreeConnect.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLFreeEnv.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLFreeHandle.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLFreeStmt.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetConnectAttr.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetConnectAttrW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetConnectOption.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetConnectOptionW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetCursorName.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetCursorNameW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetData.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetDescField.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetDescFieldW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetDescRec.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetDescRecW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetDiagField.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetDiagFieldW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetDiagRec.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetDiagRecW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetEnvAttr.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetFunctions.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetInfo.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetInfoW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetStmtAttr.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetStmtAttrW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetStmtOption.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetTypeInfo.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLGetTypeInfoW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLMoreResults.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLNativeSql.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLNativeSqlW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLNumParams.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLNumResultCols.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLParamData.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLParamOptions.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLPrepare.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLPrepareW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLPrimaryKeys.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLPrimaryKeysW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLProcedureColumns.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLProcedureColumnsW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLProcedures.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLProceduresW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLPutData.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLRowCount.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetConnectAttr.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetConnectAttrW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetConnectOption.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetConnectOptionW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetCursorName.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetCursorNameW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetDescField.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetDescFieldW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetDescRec.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetEnvAttr.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetParam.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetPos.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetScrollOptions.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetStmtAttr.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetStmtAttrW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetStmtOption.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSetStmtOptionW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSpecialColumns.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLSpecialColumnsW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLStatistics.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLStatisticsW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLTablePrivileges.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLTablePrivilegesW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLTables.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLTablesW.c
+${ODBC_SOURCE_DIR}/DriverManager/SQLTransact.c
+
+${ODBC_SOURCE_DIR}/odbcinst/_logging.c
+${ODBC_SOURCE_DIR}/odbcinst/_odbcinst_ConfigModeINI.c
+${ODBC_SOURCE_DIR}/odbcinst/ODBCINSTConstructProperties.c
+${ODBC_SOURCE_DIR}/odbcinst/ODBCINSTDestructProperties.c
+${ODBC_SOURCE_DIR}/odbcinst/_odbcinst_GetEntries.c
+${ODBC_SOURCE_DIR}/odbcinst/_odbcinst_GetSections.c
+${ODBC_SOURCE_DIR}/odbcinst/ODBCINSTSetProperty.c
+${ODBC_SOURCE_DIR}/odbcinst/_odbcinst_SystemINI.c
+${ODBC_SOURCE_DIR}/odbcinst/_odbcinst_UserINI.c
+${ODBC_SOURCE_DIR}/odbcinst/ODBCINSTValidateProperties.c
+${ODBC_SOURCE_DIR}/odbcinst/ODBCINSTValidateProperty.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLConfigDataSource.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLConfigDriver.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLCreateDataSource.c
+${ODBC_SOURCE_DIR}/odbcinst/_SQLDriverConnectPrompt.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLGetAvailableDrivers.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLGetConfigMode.c
+${ODBC_SOURCE_DIR}/odbcinst/_SQLGetInstalledDrivers.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLGetInstalledDrivers.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLGetPrivateProfileString.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLGetTranslator.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLInstallDriverEx.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLInstallDriverManager.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLInstallerError.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLInstallODBC.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLInstallTranslatorEx.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLManageDataSources.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLPostInstallerError.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLReadFileDSN.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLRemoveDriver.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLRemoveDriverManager.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLRemoveDSNFromIni.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLRemoveTranslator.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLSetConfigMode.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLValidDSN.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLWriteDSNToIni.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLWriteFileDSN.c
+${ODBC_SOURCE_DIR}/odbcinst/_SQLWriteInstalledDrivers.c
+${ODBC_SOURCE_DIR}/odbcinst/SQLWritePrivateProfileString.c
+
+${ODBC_SOURCE_DIR}/ini/iniAllTrim.c
+${ODBC_SOURCE_DIR}/ini/iniAppend.c
+${ODBC_SOURCE_DIR}/ini/iniClose.c
+${ODBC_SOURCE_DIR}/ini/iniCommit.c
+${ODBC_SOURCE_DIR}/ini/iniCursor.c
+${ODBC_SOURCE_DIR}/ini/iniDelete.c
+${ODBC_SOURCE_DIR}/ini/_iniDump.c
+${ODBC_SOURCE_DIR}/ini/iniElement.c
+${ODBC_SOURCE_DIR}/ini/iniElementCount.c
+${ODBC_SOURCE_DIR}/ini/iniGetBookmark.c
+${ODBC_SOURCE_DIR}/ini/iniGotoBookmark.c
+${ODBC_SOURCE_DIR}/ini/iniObject.c
+${ODBC_SOURCE_DIR}/ini/iniObjectDelete.c
+${ODBC_SOURCE_DIR}/ini/iniObjectEOL.c
+${ODBC_SOURCE_DIR}/ini/iniObjectFirst.c
+${ODBC_SOURCE_DIR}/ini/iniObjectInsert.c
+${ODBC_SOURCE_DIR}/ini/iniObjectLast.c
+${ODBC_SOURCE_DIR}/ini/iniObjectNext.c
+${ODBC_SOURCE_DIR}/ini/_iniObjectRead.c
+${ODBC_SOURCE_DIR}/ini/iniObjectSeek.c
+${ODBC_SOURCE_DIR}/ini/iniObjectSeekSure.c
+${ODBC_SOURCE_DIR}/ini/iniObjectUpdate.c
+${ODBC_SOURCE_DIR}/ini/iniOpen.c
+${ODBC_SOURCE_DIR}/ini/iniProperty.c
+${ODBC_SOURCE_DIR}/ini/iniPropertyDelete.c
+${ODBC_SOURCE_DIR}/ini/iniPropertyEOL.c
+${ODBC_SOURCE_DIR}/ini/iniPropertyFirst.c
+${ODBC_SOURCE_DIR}/ini/iniPropertyInsert.c
+${ODBC_SOURCE_DIR}/ini/iniPropertyLast.c
+${ODBC_SOURCE_DIR}/ini/iniPropertyNext.c
+${ODBC_SOURCE_DIR}/ini/_iniPropertyRead.c
+${ODBC_SOURCE_DIR}/ini/iniPropertySeek.c
+${ODBC_SOURCE_DIR}/ini/iniPropertySeekSure.c
+${ODBC_SOURCE_DIR}/ini/iniPropertyUpdate.c
+${ODBC_SOURCE_DIR}/ini/iniPropertyValue.c
+${ODBC_SOURCE_DIR}/ini/_iniScanUntilObject.c
+${ODBC_SOURCE_DIR}/ini/iniToUpper.c
+${ODBC_SOURCE_DIR}/ini/iniValue.c
+
+${ODBC_SOURCE_DIR}/log/logClear.c
+${ODBC_SOURCE_DIR}/log/logClose.c
+${ODBC_SOURCE_DIR}/log/_logFreeMsg.c
+${ODBC_SOURCE_DIR}/log/logOn.c
+${ODBC_SOURCE_DIR}/log/logOpen.c
+${ODBC_SOURCE_DIR}/log/logPeekMsg.c
+${ODBC_SOURCE_DIR}/log/logPopMsg.c
+${ODBC_SOURCE_DIR}/log/logPushMsg.c
+
+${ODBC_SOURCE_DIR}/lst/_lstAdjustCurrent.c
+${ODBC_SOURCE_DIR}/lst/lstAppend.c
+${ODBC_SOURCE_DIR}/lst/lstClose.c
+${ODBC_SOURCE_DIR}/lst/lstDelete.c
+${ODBC_SOURCE_DIR}/lst/_lstDump.c
+${ODBC_SOURCE_DIR}/lst/lstEOL.c
+${ODBC_SOURCE_DIR}/lst/lstFirst.c
+${ODBC_SOURCE_DIR}/lst/_lstFreeItem.c
+${ODBC_SOURCE_DIR}/lst/lstGetBookMark.c
+${ODBC_SOURCE_DIR}/lst/lstGet.c
+${ODBC_SOURCE_DIR}/lst/lstGotoBookMark.c
+${ODBC_SOURCE_DIR}/lst/lstGoto.c
+${ODBC_SOURCE_DIR}/lst/lstInsert.c
+${ODBC_SOURCE_DIR}/lst/lstLast.c
+${ODBC_SOURCE_DIR}/lst/lstNext.c
+${ODBC_SOURCE_DIR}/lst/_lstNextValidItem.c
+${ODBC_SOURCE_DIR}/lst/lstOpen.c
+${ODBC_SOURCE_DIR}/lst/lstOpenCursor.c
+${ODBC_SOURCE_DIR}/lst/lstPrev.c
+${ODBC_SOURCE_DIR}/lst/_lstPrevValidItem.c
+${ODBC_SOURCE_DIR}/lst/lstSeek.c
+${ODBC_SOURCE_DIR}/lst/lstSeekItem.c
+${ODBC_SOURCE_DIR}/lst/lstSet.c
+${ODBC_SOURCE_DIR}/lst/lstSetFreeFunc.c
+${ODBC_SOURCE_DIR}/lst/_lstVisible.c
+)
+
+add_library(unixodbc STATIC ${SRCS})
+
+target_link_libraries(unixodbc ltdl)
+
+# SYSTEM_FILE_PATH was changed to /etc
+
+target_include_directories(unixodbc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/linux_x86_64/private)
+target_include_directories(unixodbc PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/linux_x86_64)
+target_include_directories(unixodbc PUBLIC ${ODBC_SOURCE_DIR}/include)
+
+target_compile_definitions(unixodbc PRIVATE -DHAVE_CONFIG_H)
+
+target_compile_options(unixodbc PRIVATE -Wno-dangling-else -Wno-parentheses -Wno-misleading-indentation -Wno-unknown-warning-option -O2)
diff --git a/contrib/unixodbc-cmake/linux_x86_64/libltdl/config.h b/contrib/unixodbc-cmake/linux_x86_64/libltdl/config.h
new file mode 100644
index 00000000000..194779b2b98
--- /dev/null
+++ b/contrib/unixodbc-cmake/linux_x86_64/libltdl/config.h
@@ -0,0 +1,181 @@
+/* config.h. Generated from config-h.in by configure. */
+/* config-h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the `argz_add' function. */
+#define HAVE_ARGZ_ADD 1
+
+/* Define to 1 if you have the `argz_append' function. */
+#define HAVE_ARGZ_APPEND 1
+
+/* Define to 1 if you have the `argz_count' function. */
+#define HAVE_ARGZ_COUNT 1
+
+/* Define to 1 if you have the `argz_create_sep' function. */
+#define HAVE_ARGZ_CREATE_SEP 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_ARGZ_H 1
+
+/* Define to 1 if you have the `argz_insert' function. */
+#define HAVE_ARGZ_INSERT 1
+
+/* Define to 1 if you have the `argz_next' function. */
+#define HAVE_ARGZ_NEXT 1
+
+/* Define to 1 if you have the `argz_stringify' function. */
+#define HAVE_ARGZ_STRINGIFY 1
+
+/* Define to 1 if you have the `closedir' function. */
+#define HAVE_CLOSEDIR 1
+
+/* Define to 1 if you have the declaration of `cygwin_conv_path', and to 0 if
+ you don't. */
+/* #undef HAVE_DECL_CYGWIN_CONV_PATH */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the GNU dld library. */
+/* #undef HAVE_DLD */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_DLD_H */
+
+/* Define to 1 if you have the `dlerror' function. */
+#define HAVE_DLERROR 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_DL_H */
+
+/* Define if you have the _dyld_func_lookup function. */
+/* #undef HAVE_DYLD */
+
+/* Define to 1 if the system has the type `error_t'. */
+#define HAVE_ERROR_T 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define if you have the libdl library or equivalent. */
+#define HAVE_LIBDL 1
+
+/* Define if libdlloader will be built on this platform */
+#define HAVE_LIBDLLOADER 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_MACH_O_DYLD_H */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `opendir' function. */
+#define HAVE_OPENDIR 1
+
+/* Define if libtool can extract symbol lists from object files. */
+#define HAVE_PRELOADED_SYMBOLS 1
+
+/* Define to 1 if you have the `readdir' function. */
+#define HAVE_READDIR 1
+
+/* Define if you have the shl_load function. */
+/* #undef HAVE_SHL_LOAD */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcat' function. */
+/* #undef HAVE_STRLCAT */
+
+/* Define to 1 if you have the `strlcpy' function. */
+/* #undef HAVE_STRLCPY */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_DL_H */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_UNISTD_H 1
+
+/* This value is set to 1 to indicate that the system argz facility works */
+#define HAVE_WORKING_ARGZ 1
+
+/* Define if the OS needs help to load dependent libraries for dlopen(). */
+/* #undef LTDL_DLOPEN_DEPLIBS */
+
+/* Define to the system default library search path. */
+#define LT_DLSEARCH_PATH "/lib:/usr/lib:/usr/lib/x86_64-linux-gnu/libfakeroot:/usr/local/lib:/usr/local/lib/x86_64-linux-gnu:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/lib32:/usr/lib32"
+
+/* The archive extension */
+#define LT_LIBEXT "a"
+
+/* The archive prefix */
+#define LT_LIBPREFIX "lib"
+
+/* Define to the extension used for runtime loadable modules, say, ".so". */
+#define LT_MODULE_EXT ".so"
+
+/* Define to the name of the environment variable that determines the run-time
+ module search path. */
+#define LT_MODULE_PATH_VAR "LD_LIBRARY_PATH"
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Define to the shared library suffix, say, ".dylib". */
+/* #undef LT_SHARED_EXT */
+
+/* Define to the shared archive member specification, say "(shr.o)". */
+/* #undef LT_SHARED_LIB_MEMBER */
+
+/* Define if dlsym() requires a leading underscore in symbol names. */
+/* #undef NEED_USCORE */
+
+/* Name of package */
+#define PACKAGE "libltdl"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "bug-libtool@gnu.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libltdl"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libltdl 2.4.3a"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libltdl"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.4.3a"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "2.4.3a"
+
+/* Define so that glibc/gnulib argp.h does not typedef error_t. */
+/* #undef __error_t_defined */
+
+/* Define to a type to use for 'error_t' if it is not otherwise available. */
+/* #undef error_t */
diff --git a/contrib/unixodbc-cmake/linux_x86_64/libltdl/libltdlcS.c b/contrib/unixodbc-cmake/linux_x86_64/libltdl/libltdlcS.c
new file mode 100644
index 00000000000..ca866eb5986
--- /dev/null
+++ b/contrib/unixodbc-cmake/linux_x86_64/libltdl/libltdlcS.c
@@ -0,0 +1,53 @@
+/* libltdlcS.c - symbol resolution table for 'libltdlc' dlsym emulation. */
+/* Generated by libtool (GNU libtool) 2.4.6 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored "-Wstrict-prototypes"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* External symbol declarations for the compiler. */
+extern int dlopen_LTX_get_vtable();
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_libltdlc_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_libltdlc_LTX_preloaded_symbols[] =
+{ {"libltdlc", (void *) 0},
+ {"dlopen.a", (void *) 0},
+ {"dlopen_LTX_get_vtable", (void *) &dlopen_LTX_get_vtable},
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_libltdlc_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/unixodbc-cmake/linux_x86_64/private/config.h b/contrib/unixodbc-cmake/linux_x86_64/private/config.h
new file mode 100644
index 00000000000..d80a4da4665
--- /dev/null
+++ b/contrib/unixodbc-cmake/linux_x86_64/private/config.h
@@ -0,0 +1,496 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Encoding to use for CHAR */
+#define ASCII_ENCODING "auto-search"
+
+/* Install bindir */
+#define BIN_PREFIX "/usr/local/bin"
+
+/* Use a semaphore to allow ODBCConfig to display running counts */
+/* #undef COLLECT_STATS */
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to 1 if using `alloca.c'. */
+/* #undef C_ALLOCA */
+
+/* Lib directory */
+#define DEFLIB_PATH "/usr/local/lib"
+
+/* Using ini cacheing */
+#define ENABLE_INI_CACHING /**/
+
+/* Install exec_prefix */
+#define EXEC_PREFIX "/usr/local"
+
+/* Disable the precise but slow checking of the validity of handles */
+/* #undef FAST_HANDLE_VALIDATE */
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define to 1 if you have and it should be used (not on Ultrix).
+ */
+#define HAVE_ALLOCA_H 1
+
+/* Define to 1 if you have the `argz_add' function. */
+#define HAVE_ARGZ_ADD 1
+
+/* Define to 1 if you have the `argz_append' function. */
+#define HAVE_ARGZ_APPEND 1
+
+/* Define to 1 if you have the `argz_count' function. */
+#define HAVE_ARGZ_COUNT 1
+
+/* Define to 1 if you have the `argz_create_sep' function. */
+#define HAVE_ARGZ_CREATE_SEP 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_ARGZ_H 1
+
+/* Define to 1 if you have the `argz_insert' function. */
+#define HAVE_ARGZ_INSERT 1
+
+/* Define to 1 if you have the `argz_next' function. */
+#define HAVE_ARGZ_NEXT 1
+
+/* Define to 1 if you have the `argz_stringify' function. */
+#define HAVE_ARGZ_STRINGIFY 1
+
+/* Define to 1 if you have the `atoll' function. */
+#define HAVE_ATOLL 1
+
+/* Define to 1 if you have the `closedir' function. */
+#define HAVE_CLOSEDIR 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_CRYPT_H 1
+
+/* Define to 1 if you have the declaration of `cygwin_conv_path', and to 0 if
+ you don't. */
+/* #undef HAVE_DECL_CYGWIN_CONV_PATH */
+
+/* Define to 1 if you have the header file, and it defines `DIR'.
+ */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the GNU dld library. */
+/* #undef HAVE_DLD */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_DLD_H */
+
+/* Define to 1 if you have the `dlerror' function. */
+#define HAVE_DLERROR 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_DL_H */
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* Define if you have the _dyld_func_lookup function. */
+/* #undef HAVE_DYLD */
+
+/* Define to 1 if you have the `endpwent' function. */
+#define HAVE_ENDPWENT 1
+
+/* Define to 1 if the system has the type `error_t'. */
+#define HAVE_ERROR_T 1
+
+/* Define to 1 if you have the `ftime' function. */
+#define HAVE_FTIME 1
+
+/* Define to 1 if you have the `ftok' function. */
+/* #undef HAVE_FTOK */
+
+/* Define to 1 if you have the `getpwuid' function. */
+#define HAVE_GETPWUID 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the `getuid' function. */
+#define HAVE_GETUID 1
+
+/* Define if you have the iconv() function. */
+#define HAVE_ICONV 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define if you have and nl_langinfo(CODESET). */
+#define HAVE_LANGINFO_CODESET 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_LANGINFO_H 1
+
+/* Add -lcrypt to lib list */
+#define HAVE_LIBCRYPT /**/
+
+/* Define if you have the libdl library or equivalent. */
+#define HAVE_LIBDL 1
+
+/* Define if libdlloader will be built on this platform */
+#define HAVE_LIBDLLOADER 1
+
+/* Use the -lpth thread library */
+/* #undef HAVE_LIBPTH */
+
+/* Use -lpthread threading lib */
+#define HAVE_LIBPTHREAD 1
+
+/* Use the -lthread threading lib */
+/* #undef HAVE_LIBTHREAD */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_LOCALE_H 1
+
+/* Use rentrant version of localtime */
+#define HAVE_LOCALTIME_R 1
+
+/* Define if you have long long */
+#define HAVE_LONG_LONG 1
+
+/* Define this if a modern libltdl is already installed */
+#define HAVE_LTDL 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_MACH_O_DYLD_H */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_MSQL_H */
+
+/* Define to 1 if you have the header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the `nl_langinfo' function. */
+#define HAVE_NL_LANGINFO 1
+
+/* Define to 1 if you have the `opendir' function. */
+#define HAVE_OPENDIR 1
+
+/* Define if libtool can extract symbol lists from object files. */
+#define HAVE_PRELOADED_SYMBOLS 1
+
+/* Define to 1 if the system has the type `ptrdiff_t'. */
+#define HAVE_PTRDIFF_T 1
+
+/* Define to 1 if you have the `putenv' function. */
+#define HAVE_PUTENV 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_PWD_H 1
+
+/* Define to 1 if you have the `readdir' function. */
+#define HAVE_READDIR 1
+
+/* Add readline support */
+#define HAVE_READLINE 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_READLINE_HISTORY_H 1
+
+/* Use the scandir lib */
+/* #undef HAVE_SCANDIR */
+
+/* Define to 1 if you have the `semget' function. */
+/* #undef HAVE_SEMGET */
+
+/* Define to 1 if you have the `semop' function. */
+/* #undef HAVE_SEMOP */
+
+/* Define to 1 if you have the `setenv' function. */
+#define HAVE_SETENV 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define if you have the shl_load function. */
+/* #undef HAVE_SHL_LOAD */
+
+/* Define to 1 if you have the `shmget' function. */
+/* #undef HAVE_SHMGET */
+
+/* Define to 1 if you have the `snprintf' function. */
+/* #undef HAVE_SNPRINTF */
+
+/* Define to 1 if you have the `socket' function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `stricmp' function. */
+/* #undef HAVE_STRICMP */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcat' function. */
+/* #undef HAVE_STRLCAT */
+
+/* Define to 1 if you have the `strlcpy' function. */
+/* #undef HAVE_STRLCPY */
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the `strnicmp' function. */
+/* #undef HAVE_STRNICMP */
+
+/* Define to 1 if you have the `strstr' function. */
+#define HAVE_STRSTR 1
+
+/* Define to 1 if you have the `strtol' function. */
+#define HAVE_STRTOL 1
+
+/* Define to 1 if you have the `strtoll' function. */
+#define HAVE_STRTOLL 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYNCH_H */
+
+/* Define to 1 if you have the header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_DL_H */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_MALLOC_H */
+
+/* Define to 1 if you have the header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_SEM_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_TIMEB_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the `time' function. */
+#define HAVE_TIME 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_VARARGS_H */
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* This value is set to 1 to indicate that the system argz facility works */
+#define HAVE_WORKING_ARGZ 1
+
+/* Define as const if the declaration of iconv() needs const. */
+#define ICONV_CONST
+
+/* Install includedir */
+#define INCLUDE_PREFIX "/usr/local/include"
+
+/* Lib directory */
+#define LIB_PREFIX "/usr/local/lib"
+
+/* Define if the OS needs help to load dependent libraries for dlopen(). */
+/* #undef LTDL_DLOPEN_DEPLIBS */
+
+/* Define to the system default library search path. */
+#define LT_DLSEARCH_PATH "/lib:/usr/lib:/usr/lib/x86_64-linux-gnu/libfakeroot:/usr/local/lib:/usr/local/lib/x86_64-linux-gnu:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/lib32:/usr/lib32"
+
+/* The archive extension */
+#define LT_LIBEXT "a"
+
+/* The archive prefix */
+#define LT_LIBPREFIX "lib"
+
+/* Define to the extension used for runtime loadable modules, say, ".so". */
+#define LT_MODULE_EXT ".so"
+
+/* Define to the name of the environment variable that determines the run-time
+ module search path. */
+#define LT_MODULE_PATH_VAR "LD_LIBRARY_PATH"
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Define to the shared library suffix, say, ".dylib". */
+/* #undef LT_SHARED_EXT */
+
+/* Define to the shared archive member specification, say "(shr.o)". */
+/* #undef LT_SHARED_LIB_MEMBER */
+
+/* Define if you need semundo union */
+/* #undef NEED_SEMUNDO_UNION */
+
+/* Define if dlsym() requires a leading underscore in symbol names. */
+/* #undef NEED_USCORE */
+
+/* Using OSX */
+/* #undef OSXHEADER */
+
+/* Name of package */
+#define PACKAGE "unixODBC"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "nick@unixodbc.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "unixODBC"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "unixODBC 2.3.6"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "unixODBC"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.3.6"
+
+/* Platform is 64 bit */
+#define PLATFORM64 /**/
+
+/* Install prefix */
+#define PREFIX "/usr/local"
+
+/* Using QNX */
+/* #undef QNX_LIBLTDL */
+
+/* Shared lib extension */
+#define SHLIBEXT ".so"
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 8
+
+/* The size of `long int', as computed by sizeof. */
+#define SIZEOF_LONG_INT 8
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+/* #undef STACK_DIRECTION */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* don't include unixODBC prefix in driver error messages */
+#define STRICT_ODBC_ERROR /**/
+
+/* System file path */
+#define SYSTEM_FILE_PATH "/etc"
+
+/* Lib path */
+#define SYSTEM_LIB_PATH "/usr/local/lib"
+
+/* Define to 1 if you can safely include both and . */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to 1 if your declares `struct tm'. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Encoding to use for UNICODE */
+#define UNICODE_ENCODING "auto-search"
+
+/* Flag that we are not using another DM */
+#define UNIXODBC /**/
+
+/* We are building inside the unixODBC source tree */
+#define UNIXODBC_SOURCE /**/
+
+/* Version number of package */
+#define VERSION "2.3.6"
+
+/* Work with IBM drivers that use 32 bit handles on 64 bit platforms */
+/* #undef WITH_HANDLE_REDIRECT */
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+/* #undef YYTEXT_POINTER */
+
+/* Build flag for AIX */
+/* #undef _ALL_SOURCE */
+
+/* Build flag for AIX */
+/* #undef _LONG_LONG */
+
+/* Build flag for AIX */
+/* #undef _THREAD_SAFE */
+
+/* Define so that glibc/gnulib argp.h does not typedef error_t. */
+/* #undef __error_t_defined */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to a type to use for 'error_t' if it is not otherwise available. */
+/* #undef error_t */
+
+/* Define to `int' if doesn't define. */
+/* #undef gid_t */
+
+/* Define to `unsigned int' if does not define. */
+/* #undef size_t */
+
+/* Define to `int' if doesn't define. */
+/* #undef uid_t */
diff --git a/contrib/unixodbc-cmake/linux_x86_64/unixodbc_conf.h b/contrib/unixodbc-cmake/linux_x86_64/unixodbc_conf.h
new file mode 100644
index 00000000000..6597c85cea6
--- /dev/null
+++ b/contrib/unixodbc-cmake/linux_x86_64/unixodbc_conf.h
@@ -0,0 +1,60 @@
+/* unixodbc_conf.h. Generated from unixodbc_conf.h.in by configure. */
+#ifndef HAVE_UNISTD_H
+#define HAVE_UNISTD_H 1
+#endif
+
+#ifndef HAVE_PWD_H
+#define HAVE_PWD_H 1
+#endif
+
+#ifndef HAVE_SYS_TIME_H
+#define HAVE_SYS_TIME_H 1
+#endif
+
+#ifndef ODBC_STD
+/* #undef ODBC_STD */
+#endif
+
+#ifndef UNICODE
+/* #undef UNICODE */
+#endif
+
+#ifndef GUID_DEFINED
+/* #undef GUID_DEFINED */
+#endif
+
+#ifndef SQL_WCHART_CONVERT
+/* #undef SQL_WCHART_CONVERT */
+#endif
+
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG 1
+#endif
+
+#ifndef ODBCINT64_TYPEA
+/* #undef ODBCINT64_TYPEA */
+#endif
+
+#ifndef UODBCINT64_TYPE
+/* #undef UODBCINT64_TYPE */
+#endif
+
+#ifndef DISABLE_INI_CACHING
+/* #undef DISABLE_INI_CACHING */
+#endif
+
+#ifndef SIZEOF_LONG_INT
+#define SIZEOF_LONG_INT 8
+#endif
+
+#ifndef ALLREADY_HAVE_WINDOWS_TYPE
+/* #undef ALLREADY_HAVE_WINDOWS_TYPE */
+#endif
+
+#ifndef DONT_TD_VOID
+/* #undef DONT_TD_VOID */
+#endif
+
+#ifndef DO_YOU_KNOW_WHAT_YOUR_ARE_DOING
+/* #undef DO_YOU_KNOW_WHAT_YOUR_ARE_DOING */
+#endif
diff --git a/dbms/CMakeLists.txt b/dbms/CMakeLists.txt
index eaf21b0b6ac..91d5b7676a2 100644
--- a/dbms/CMakeLists.txt
+++ b/dbms/CMakeLists.txt
@@ -53,6 +53,7 @@ add_headers_and_sources(dbms src/Interpreters/ClusterProxy)
add_headers_and_sources(dbms src/Columns)
add_headers_and_sources(dbms src/Storages)
add_headers_and_sources(dbms src/Storages/Distributed)
+add_headers_and_sources(dbms src/Storages/Kafka)
add_headers_and_sources(dbms src/Storages/MergeTree)
add_headers_and_sources(dbms src/Client)
add_headers_and_sources(dbms src/Formats)
@@ -84,7 +85,7 @@ list (APPEND dbms_headers src/TableFunctions/ITableFunction.h src/TableFunctions
add_library(clickhouse_common_io ${SPLIT_SHARED} ${clickhouse_common_io_headers} ${clickhouse_common_io_sources})
-if (ARCH_FREEBSD)
+if (OS_FREEBSD)
target_compile_definitions (clickhouse_common_io PUBLIC CLOCK_MONOTONIC_COARSE=CLOCK_MONOTONIC_FAST)
endif ()
@@ -144,6 +145,7 @@ target_link_libraries (clickhouse_common_io
${EXECINFO_LIBRARY}
${ELF_LIBRARY}
${Boost_SYSTEM_LIBRARY}
+ apple_rt
${CMAKE_DL_LIBS}
)
@@ -244,8 +246,6 @@ add_subdirectory (programs)
add_subdirectory (tests)
if (ENABLE_TESTS)
- include (${ClickHouse_SOURCE_DIR}/cmake/find_gtest.cmake)
-
if (USE_INTERNAL_GTEST_LIBRARY)
# Google Test from sources
add_subdirectory(${ClickHouse_SOURCE_DIR}/contrib/googletest/googletest ${CMAKE_CURRENT_BINARY_DIR}/googletest)
diff --git a/dbms/cmake/version.cmake b/dbms/cmake/version.cmake
index 131e6f26aaa..4e1fb44caa4 100644
--- a/dbms/cmake/version.cmake
+++ b/dbms/cmake/version.cmake
@@ -1,11 +1,11 @@
# This strings autochanged from release_lib.sh:
-set(VERSION_REVISION 54396 CACHE STRING "")
+set(VERSION_REVISION 54404 CACHE STRING "")
set(VERSION_MAJOR 18 CACHE STRING "")
-set(VERSION_MINOR 1 CACHE STRING "")
+set(VERSION_MINOR 9 CACHE STRING "")
set(VERSION_PATCH 0 CACHE STRING "")
-set(VERSION_GITHASH 550f41bc65cb03201acad489e7b96ea346ed8259 CACHE STRING "")
-set(VERSION_DESCRIBE v18.1.0-testing CACHE STRING "")
-set(VERSION_STRING 18.1.0 CACHE STRING "")
+set(VERSION_GITHASH c83721a02db002eef7ff864f82d53ca89d47f9e6 CACHE STRING "")
+set(VERSION_DESCRIBE v18.9.0-testing CACHE STRING "")
+set(VERSION_STRING 18.9.0 CACHE STRING "")
# end of autochange
set(VERSION_EXTRA "" CACHE STRING "")
@@ -14,18 +14,11 @@ set(VERSION_TWEAK "" CACHE STRING "")
if (VERSION_TWEAK)
string(CONCAT VERSION_STRING ${VERSION_STRING} "." ${VERSION_TWEAK})
endif ()
+
if (VERSION_EXTRA)
string(CONCAT VERSION_STRING ${VERSION_STRING} "." ${VERSION_EXTRA})
endif ()
-set (VERSION_NAME "${PROJECT_NAME}")
-set (VERSION_FULL "${VERSION_NAME} ${VERSION_STRING}")
-
-if (APPLE)
- # dirty hack: ld: malformed 64-bit a.b.c.d.e version number: 1.1.54160
- math (EXPR VERSION_SO1 "${VERSION_REVISION}/255")
- math (EXPR VERSION_SO2 "${VERSION_REVISION}%255")
- set (VERSION_SO "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_SO1}.${VERSION_SO2}")
-else ()
- set (VERSION_SO "${VERSION_STRING}")
-endif ()
+set (VERSION_NAME "${PROJECT_NAME}" CACHE STRING "")
+set (VERSION_FULL "${VERSION_NAME} ${VERSION_STRING}" CACHE STRING "")
+set (VERSION_SO "${VERSION_STRING}" CACHE STRING "")
diff --git a/dbms/programs/CMakeLists.txt b/dbms/programs/CMakeLists.txt
index 20baa6b039c..a5692d81c09 100644
--- a/dbms/programs/CMakeLists.txt
+++ b/dbms/programs/CMakeLists.txt
@@ -152,6 +152,6 @@ else ()
endif ()
-if (USE_EMBEDDED_COMPILER AND ENABLE_CLICKHOUSE_SERVER)
+if (TARGET clickhouse-server AND TARGET copy-headers)
add_dependencies(clickhouse-server copy-headers)
endif ()
diff --git a/dbms/programs/clang/Compiler-5.0.0/CMakeLists.txt b/dbms/programs/clang/Compiler-5.0.0/CMakeLists.txt
index e07a570a434..d02d266d5a5 100644
--- a/dbms/programs/clang/Compiler-5.0.0/CMakeLists.txt
+++ b/dbms/programs/clang/Compiler-5.0.0/CMakeLists.txt
@@ -43,4 +43,7 @@ LLVMSupport
#PollyPPCG
PUBLIC ${ZLIB_LIBRARIES} ${EXECINFO_LIBRARY} Threads::Threads
+${MALLOC_LIBRARIES}
+${GLIBC_COMPATIBILITY_LIBRARIES}
+${MEMCPY_LIBRARIES}
)
diff --git a/dbms/programs/clang/Compiler-6.0.0/CMakeLists.txt b/dbms/programs/clang/Compiler-6.0.0/CMakeLists.txt
index 4f5e703bd63..701b99d08e3 100644
--- a/dbms/programs/clang/Compiler-6.0.0/CMakeLists.txt
+++ b/dbms/programs/clang/Compiler-6.0.0/CMakeLists.txt
@@ -43,4 +43,7 @@ ${REQUIRED_LLVM_LIBRARIES}
#PollyPPCG
PUBLIC ${ZLIB_LIBRARIES} ${EXECINFO_LIBRARY} Threads::Threads
+${MALLOC_LIBRARIES}
+${GLIBC_COMPATIBILITY_LIBRARIES}
+${MEMCPY_LIBRARIES}
)
diff --git a/dbms/programs/clang/Compiler-7.0.0/CMakeLists.txt b/dbms/programs/clang/Compiler-7.0.0/CMakeLists.txt
index f46e8ef0dc1..081037cdeed 100644
--- a/dbms/programs/clang/Compiler-7.0.0/CMakeLists.txt
+++ b/dbms/programs/clang/Compiler-7.0.0/CMakeLists.txt
@@ -39,4 +39,7 @@ lldCore
${REQUIRED_LLVM_LIBRARIES}
PUBLIC ${ZLIB_LIBRARIES} ${EXECINFO_LIBRARY} Threads::Threads
+${MALLOC_LIBRARIES}
+${GLIBC_COMPATIBILITY_LIBRARIES}
+${MEMCPY_LIBRARIES}
)
diff --git a/dbms/programs/client/Client.cpp b/dbms/programs/client/Client.cpp
index eb7673c947b..a52dadcc5dc 100644
--- a/dbms/programs/client/Client.cpp
+++ b/dbms/programs/client/Client.cpp
@@ -86,9 +86,106 @@ namespace ErrorCodes
extern const int UNKNOWN_PACKET_FROM_SERVER;
extern const int UNEXPECTED_PACKET_FROM_SERVER;
extern const int CLIENT_OUTPUT_FORMAT_SPECIFIED;
+ extern const int LOGICAL_ERROR;
}
+/// Checks expected server and client error codes in testmode.
+/// To enable it add special comment after the query: "-- { serverError 60 }" or "-- { clientError 20 }".
+class TestHint
+{
+public:
+ TestHint(bool enabled_, const String & query)
+ : enabled(enabled_),
+ server_error(0),
+ client_error(0)
+ {
+ if (!enabled_)
+ return;
+
+ size_t pos = query.find("--");
+ if (pos != String::npos && query.find("--", pos + 2) != String::npos)
+ return; /// It's not last comment. Hint belongs to commented query.
+
+ if (pos != String::npos)
+ {
+ pos = query.find('{', pos + 2);
+ if (pos != String::npos)
+ {
+ String hint = query.substr(pos + 1);
+ pos = hint.find('}');
+ hint.resize(pos);
+ parse(hint);
+ }
+ }
+ }
+
+ /// @returns true if it's possible to continue without reconnect
+ bool checkActual(int & actual_server_error, int & actual_client_error,
+ bool & got_exception, std::unique_ptr & last_exception) const
+ {
+ if (!enabled)
+ return true;
+
+ if (allErrorsExpected(actual_server_error, actual_client_error))
+ {
+ got_exception = false;
+ last_exception.reset();
+ actual_server_error = 0;
+ actual_client_error = 0;
+ return false;
+ }
+
+ if (lostExpectedError(actual_server_error, actual_client_error))
+ {
+ std::cerr << "Success when error expected. It expects server error "
+ << server_error << ", client error " << client_error << "." << std::endl;
+ got_exception = true;
+ last_exception = std::make_unique("Success when error expected", ErrorCodes::LOGICAL_ERROR); /// return error to OS
+ return false;
+ }
+
+ return true;
+ }
+
+ int serverError() const { return server_error; }
+ int clientError() const { return client_error; }
+
+private:
+ bool enabled;
+ int server_error;
+ int client_error;
+
+ void parse(const String & hint)
+ {
+ std::stringstream ss;
+ ss << hint;
+ while (!ss.eof())
+ {
+ String item;
+ ss >> item;
+ if (item.empty())
+ break;
+
+ if (item == "serverError")
+ ss >> server_error;
+ else if (item == "clientError")
+ ss >> client_error;
+ }
+ }
+
+ bool allErrorsExpected(int actual_server_error, int actual_client_error) const
+ {
+ return (server_error || client_error) && (server_error == actual_server_error) && (client_error == actual_client_error);
+ }
+
+ bool lostExpectedError(int actual_server_error, int actual_client_error) const
+ {
+ return (server_error && !actual_server_error) || (client_error && !actual_client_error);
+ }
+};
+
+
class Client : public Poco::Util::Application
{
public:
@@ -107,6 +204,7 @@ private:
bool is_interactive = true; /// Use either readline interface or batch mode.
bool need_render_progress = true; /// Render query execution progress.
bool echo_queries = false; /// Print queries before execution in batch mode.
+ bool ignore_error = false; /// In case of errors, don't print error message, continue to next query. Only applicable for non-interactive mode.
bool print_time_to_stderr = false; /// Output execution time to stderr in batch mode.
bool stdin_is_not_tty = false; /// stdin is not a terminal.
@@ -157,6 +255,10 @@ private:
/// If the last query resulted in exception.
bool got_exception = false;
+ int expected_server_error = 0;
+ int expected_client_error = 0;
+ int actual_server_error = 0;
+ int actual_client_error = 0;
String server_version;
String server_display_name;
@@ -373,6 +475,7 @@ private:
{
need_render_progress = config().getBool("progress", false);
echo_queries = config().getBool("echo", false);
+ ignore_error = config().getBool("ignore-error", false);
}
connect();
@@ -515,6 +618,7 @@ private:
String server_name;
UInt64 server_version_major = 0;
UInt64 server_version_minor = 0;
+ UInt64 server_version_patch = 0;
UInt64 server_revision = 0;
if (max_client_network_bandwidth)
@@ -523,9 +627,9 @@ private:
connection->setThrottler(throttler);
}
- connection->getServerVersion(server_name, server_version_major, server_version_minor, server_revision);
+ connection->getServerVersion(server_name, server_version_major, server_version_minor, server_version_patch, server_revision);
- server_version = toString(server_version_major) + "." + toString(server_version_minor) + "." + toString(server_revision);
+ server_version = toString(server_version_major) + "." + toString(server_version_minor) + "." + toString(server_version_patch);
if (server_display_name = connection->getServerDisplayName(); server_display_name.length() == 0)
{
@@ -536,6 +640,7 @@ private:
{
std::cout << "Connected to " << server_name
<< " server version " << server_version
+ << " revision " << server_revision
<< "." << std::endl << std::endl;
}
}
@@ -617,10 +722,14 @@ private:
}
catch (const Exception & e)
{
- std::cerr << std::endl
- << "Exception on client:" << std::endl
- << "Code: " << e.code() << ". " << e.displayText() << std::endl
- << std::endl;
+ actual_client_error = e.code();
+ if (!actual_client_error || actual_client_error != expected_client_error)
+ {
+ std::cerr << std::endl
+ << "Exception on client:" << std::endl
+ << "Code: " << e.code() << ". " << e.displayText() << std::endl
+ << std::endl;
+ }
/// Client-side exception during query execution can result in the loss of
/// sync in the connection protocol.
@@ -658,7 +767,7 @@ private:
bool process(const String & text)
{
- const auto ignore_error = config().getBool("ignore-error", false);
+ const bool test_mode = config().has("testmode");
if (config().has("multiquery"))
{
/// Several queries separated by ';'.
@@ -702,6 +811,10 @@ private:
while (isWhitespaceASCII(*begin) || *begin == ';')
++begin;
+ TestHint test_hint(test_mode, query);
+ expected_client_error = test_hint.clientError();
+ expected_server_error = test_hint.serverError();
+
try
{
if (!processSingleQuery(query, ast) && !ignore_error)
@@ -709,10 +822,16 @@ private:
}
catch (...)
{
- std::cerr << "Error on processing query: " << query << std::endl << getCurrentExceptionMessage(true);
+ last_exception = std::make_unique(getCurrentExceptionMessage(true), getCurrentExceptionCode());
+ actual_client_error = last_exception->code();
+ if (!ignore_error && (!actual_client_error || actual_client_error != expected_client_error))
+ std::cerr << "Error on processing query: " << query << std::endl << last_exception->message();
got_exception = true;
}
+ if (!test_hint.checkActual(actual_server_error, actual_client_error, got_exception, last_exception))
+ connection->forceConnected();
+
if (got_exception && !ignore_error)
{
if (is_interactive)
@@ -1286,6 +1405,14 @@ private:
resetOutput();
got_exception = true;
+ actual_server_error = e.code();
+ if (expected_server_error)
+ {
+ if (actual_server_error == expected_server_error)
+ return;
+ std::cerr << "Expected error code: " << expected_server_error << " but got: " << actual_server_error << "." << std::endl;
+ }
+
std::string text = e.displayText();
auto embedded_stack_trace_pos = text.find("Stack trace");
@@ -1411,7 +1538,8 @@ public:
("pager", boost::program_options::value(), "pager")
("multiline,m", "multiline")
("multiquery,n", "multiquery")
- ("ignore-error", "Do not stop processing in multiquery mode")
+ ("testmode,T", "enable test hints in comments")
+ ("ignore-error", "do not stop processing in multiquery mode")
("format,f", boost::program_options::value(), "default output format")
("vertical,E", "vertical output format, same as --format=Vertical or FORMAT Vertical or \\G at end of command")
("time,t", "print query execution time to stderr in non-interactive mode (for benchmarks)")
@@ -1517,6 +1645,8 @@ public:
config().setBool("multiline", true);
if (options.count("multiquery"))
config().setBool("multiquery", true);
+ if (options.count("testmode"))
+ config().setBool("testmode", true);
if (options.count("ignore-error"))
config().setBool("ignore-error", true);
if (options.count("format"))
diff --git a/dbms/programs/obfuscator/Obfuscator.cpp b/dbms/programs/obfuscator/Obfuscator.cpp
index 854771b3b26..3ba6d76179e 100644
--- a/dbms/programs/obfuscator/Obfuscator.cpp
+++ b/dbms/programs/obfuscator/Obfuscator.cpp
@@ -58,13 +58,13 @@ It is designed to retain the following properties of data:
Most of the properties above are viable for performance testing:
- reading data, filtering, aggregation and sorting will work at almost the same speed
- as on original data due to saved cardinalities, magnitudes, compression ratios, etc.
+ as on original data due to saved cardinalities, magnitudes, compression ratios, etc.
It works in deterministic fashion: you define a seed value and transform is totally determined by input data and by seed.
Some transforms are one to one and could be reversed, so you need to have large enough seed and keep it in secret.
It use some cryptographic primitives to transform data, but from the cryptographic point of view,
- it doesn't do anything properly and you should never consider the result as secure, unless you have other reasons for it.
+ it doesn't do anything properly and you should never consider the result as secure, unless you have other reasons for it.
It may retain some data you don't want to publish.
@@ -74,7 +74,7 @@ So, the user will be able to count exact ratio of mobile traffic.
Another example, suppose you have some private data in your table, like user email and you don't want to publish any single email address.
If your table is large enough and contain multiple different emails and there is no email that have very high frequency than all others,
- it will perfectly anonymize all data. But if you have small amount of different values in a column, it can possibly reproduce some of them.
+ it will perfectly anonymize all data. But if you have small amount of different values in a column, it can possibly reproduce some of them.
And you should take care and look at exact algorithm, how this tool works, and probably fine tune some of it command line parameters.
This tool works fine only with reasonable amount of data (at least 1000s of rows).
diff --git a/dbms/programs/performance-test/PerformanceTest.cpp b/dbms/programs/performance-test/PerformanceTest.cpp
index 1f7421566a4..cf55173ad3a 100644
--- a/dbms/programs/performance-test/PerformanceTest.cpp
+++ b/dbms/programs/performance-test/PerformanceTest.cpp
@@ -521,11 +521,12 @@ public:
std::string name;
UInt64 version_major;
UInt64 version_minor;
+ UInt64 version_patch;
UInt64 version_revision;
- connection.getServerVersion(name, version_major, version_minor, version_revision);
+ connection.getServerVersion(name, version_major, version_minor, version_patch, version_revision);
std::stringstream ss;
- ss << version_major << "." << version_minor << "." << version_revision;
+ ss << version_major << "." << version_minor << "." << version_patch;
server_version = ss.str();
processTestsConfigurations(input_files);
diff --git a/dbms/programs/server/CMakeLists.txt b/dbms/programs/server/CMakeLists.txt
index 74297d29864..c146f40d281 100644
--- a/dbms/programs/server/CMakeLists.txt
+++ b/dbms/programs/server/CMakeLists.txt
@@ -19,7 +19,7 @@ if (CLICKHOUSE_SPLIT_BINARY)
install (TARGETS clickhouse-server ${CLICKHOUSE_ALL_TARGETS} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
endif ()
-if (NOT APPLE AND NOT ARCH_FREEBSD)
+if (OS_LINUX)
set (GLIBC_MAX_REQUIRED 2.4)
add_test(NAME GLIBC_required_version COMMAND bash -c "readelf -s ${CMAKE_CURRENT_BINARY_DIR}/../clickhouse-server | grep '@GLIBC' | grep -oP 'GLIBC_[\\d\\.]+' | sort | uniq | sort -r | perl -lnE 'exit 1 if $_ gt q{GLIBC_${GLIBC_MAX_REQUIRED}}'")
endif ()
diff --git a/dbms/programs/server/InterserverIOHTTPHandler.cpp b/dbms/programs/server/InterserverIOHTTPHandler.cpp
index 3cdbaa69b64..39d214503ba 100644
--- a/dbms/programs/server/InterserverIOHTTPHandler.cpp
+++ b/dbms/programs/server/InterserverIOHTTPHandler.cpp
@@ -1,3 +1,4 @@
+#include
#include
#include
@@ -23,14 +24,40 @@ namespace ErrorCodes
extern const int TOO_MANY_SIMULTANEOUS_QUERIES;
}
+std::pair InterserverIOHTTPHandler::checkAuthentication(Poco::Net::HTTPServerRequest & request) const
+{
+ const auto & config = server.config();
+
+ if (config.has("interserver_http_credentials.user"))
+ {
+ if (!request.hasCredentials())
+ return {"Server requires HTTP Basic authentification, but client doesn't provide it", false};
+ String scheme, info;
+ request.getCredentials(scheme, info);
+
+ if (scheme != "Basic")
+ return {"Server requires HTTP Basic authentification but client provides another method", false};
+
+ String user = config.getString("interserver_http_credentials.user");
+ String password = config.getString("interserver_http_credentials.password", "");
+
+ Poco::Net::HTTPBasicCredentials credentials(info);
+ if (std::make_pair(user, password) != std::make_pair(credentials.getUsername(), credentials.getPassword()))
+ return {"Incorrect user or password in HTTP Basic authentification", false};
+ }
+ else if (request.hasCredentials())
+ {
+ return {"Client requires HTTP Basic authentification, but server doesn't provide it", false};
+ }
+ return {"", true};
+}
+
void InterserverIOHTTPHandler::processQuery(Poco::Net::HTTPServerRequest & request, Poco::Net::HTTPServerResponse & response)
{
HTMLForm params(request);
LOG_TRACE(log, "Request URI: " << request.getURI());
- /// NOTE: You can do authentication here if you need to.
-
String endpoint_name = params.get("endpoint");
bool compress = params.get("compress") == "true";
@@ -65,8 +92,18 @@ void InterserverIOHTTPHandler::handleRequest(Poco::Net::HTTPServerRequest & requ
try
{
- processQuery(request, response);
- LOG_INFO(log, "Done processing query");
+ if (auto [msg, success] = checkAuthentication(request); success)
+ {
+ processQuery(request, response);
+ LOG_INFO(log, "Done processing query");
+ }
+ else
+ {
+ response.setStatusAndReason(Poco::Net::HTTPServerResponse::HTTP_UNAUTHORIZED);
+ if (!response.sent())
+ response.send() << msg << std::endl;
+ LOG_WARNING(log, "Query processing failed request: '" << request.getURI() << "' authentification failed");
+ }
}
catch (Exception & e)
{
diff --git a/dbms/programs/server/InterserverIOHTTPHandler.h b/dbms/programs/server/InterserverIOHTTPHandler.h
index bf9fef59982..fbaf432d4f9 100644
--- a/dbms/programs/server/InterserverIOHTTPHandler.h
+++ b/dbms/programs/server/InterserverIOHTTPHandler.h
@@ -34,6 +34,8 @@ private:
CurrentMetrics::Increment metric_increment{CurrentMetrics::InterserverConnection};
void processQuery(Poco::Net::HTTPServerRequest & request, Poco::Net::HTTPServerResponse & response);
+
+ std::pair checkAuthentication(Poco::Net::HTTPServerRequest & request) const;
};
}
diff --git a/dbms/programs/server/Server.cpp b/dbms/programs/server/Server.cpp
index 9a3db8bdb12..153f48c9aef 100644
--- a/dbms/programs/server/Server.cpp
+++ b/dbms/programs/server/Server.cpp
@@ -58,6 +58,7 @@ namespace ErrorCodes
extern const int NO_ELEMENTS_IN_CONFIG;
extern const int SUPPORT_IS_DISABLED;
extern const int ARGUMENT_OUT_OF_BOUND;
+ extern const int EXCESSIVE_ELEMENT_IN_CONFIG;
}
@@ -209,25 +210,49 @@ int Server::main(const std::vector & /*args*/)
Poco::File(user_files_path).createDirectories();
}
- if (config().has("interserver_http_port"))
+ if (config().has("interserver_http_port") && config().has("interserver_https_port"))
+ throw Exception("Both http and https interserver ports are specified", ErrorCodes::EXCESSIVE_ELEMENT_IN_CONFIG);
+
+ static const auto interserver_tags =
{
- String this_host = config().getString("interserver_http_host", "");
+ std::make_tuple("interserver_http_host", "interserver_http_port", "http"),
+ std::make_tuple("interserver_https_host", "interserver_https_port", "https")
+ };
- if (this_host.empty())
+ for (auto [host_tag, port_tag, scheme] : interserver_tags)
+ {
+ if (config().has(port_tag))
{
- this_host = getFQDNOrHostName();
- LOG_DEBUG(log,
- "Configuration parameter 'interserver_http_host' doesn't exist or exists and empty. Will use '" + this_host
- + "' as replica host.");
+ String this_host = config().getString(host_tag, "");
+
+ if (this_host.empty())
+ {
+ this_host = getFQDNOrHostName();
+ LOG_DEBUG(log,
+ "Configuration parameter '" + String(host_tag) + "' doesn't exist or exists and empty. Will use '" + this_host
+ + "' as replica host.");
+ }
+
+ String port_str = config().getString(port_tag);
+ int port = parse(port_str);
+
+ if (port < 0 || port > 0xFFFF)
+ throw Exception("Out of range '" + String(port_tag) + "': " + toString(port), ErrorCodes::ARGUMENT_OUT_OF_BOUND);
+
+ global_context->setInterserverIOAddress(this_host, port);
+ global_context->setInterserverScheme(scheme);
}
+ }
- String port_str = config().getString("interserver_http_port");
- int port = parse(port_str);
+ if (config().has("interserver_http_credentials"))
+ {
+ String user = config().getString("interserver_http_credentials.user", "");
+ String password = config().getString("interserver_http_credentials.password", "");
- if (port < 0 || port > 0xFFFF)
- throw Exception("Out of range 'interserver_http_port': " + toString(port), ErrorCodes::ARGUMENT_OUT_OF_BOUND);
+ if (user.empty())
+ throw Exception("Configuration parameter interserver_http_credentials user can't be empty", ErrorCodes::NO_ELEMENTS_IN_CONFIG);
- global_context->setInterserverIOAddress(this_host, port);
+ global_context->setInterserverCredentials(user, password);
}
if (config().has("macros"))
@@ -276,6 +301,9 @@ int Server::main(const std::vector & /*args*/)
if (config().has("max_table_size_to_drop"))
global_context->setMaxTableSizeToDrop(config().getUInt64("max_table_size_to_drop"));
+ if (config().has("max_partition_size_to_drop"))
+ global_context->setMaxPartitionSizeToDrop(config().getUInt64("max_partition_size_to_drop"));
+
/// Size of cache for uncompressed blocks. Zero means disabled.
size_t uncompressed_cache_size = config().getUInt64("uncompressed_cache_size", 0);
if (uncompressed_cache_size)
@@ -505,6 +533,27 @@ int Server::main(const std::vector & /*args*/)
LOG_INFO(log, "Listening interserver http: " + address.toString());
}
+
+ if (config().has("interserver_https_port"))
+ {
+#if USE_POCO_NETSSL
+ initSSL();
+ Poco::Net::SecureServerSocket socket;
+ auto address = socket_bind_listen(socket, listen_host, config().getInt("interserver_https_port"), /* secure = */ true);
+ socket.setReceiveTimeout(settings.http_receive_timeout);
+ socket.setSendTimeout(settings.http_send_timeout);
+ servers.emplace_back(new Poco::Net::HTTPServer(
+ new InterserverIOHTTPHandlerFactory(*this, "InterserverIOHTTPHandler-factory"),
+ server_pool,
+ socket,
+ http_params));
+
+ LOG_INFO(log, "Listening interserver https: " + address.toString());
+#else
+ throw Exception{"SSL support for TCP protocol is disabled because Poco library was built without NetSSL support.",
+ ErrorCodes::SUPPORT_IS_DISABLED};
+#endif
+ }
}
catch (const Poco::Net::NetException & e)
{
diff --git a/dbms/programs/server/TCPHandler.cpp b/dbms/programs/server/TCPHandler.cpp
index 26c8ce29130..4f75f7dd6a7 100644
--- a/dbms/programs/server/TCPHandler.cpp
+++ b/dbms/programs/server/TCPHandler.cpp
@@ -24,7 +24,6 @@
#include
#include
-
namespace DB
{
@@ -494,6 +493,7 @@ void TCPHandler::receiveHello()
readStringBinary(client_name, *in);
readVarUInt(client_version_major, *in);
readVarUInt(client_version_minor, *in);
+ // NOTE For backward compatibility of the protocol, client cannot send its version_patch.
readVarUInt(client_revision, *in);
readStringBinary(default_database, *in);
readStringBinary(user, *in);
@@ -502,7 +502,8 @@ void TCPHandler::receiveHello()
LOG_DEBUG(log, "Connected " << client_name
<< " version " << client_version_major
<< "." << client_version_minor
- << "." << client_revision
+ << "." << client_version_patch
+ << ", revision: " << client_revision
<< (!default_database.empty() ? ", database: " + default_database : "")
<< (!user.empty() ? ", user: " + user : "")
<< ".");
@@ -519,13 +520,11 @@ void TCPHandler::sendHello()
writeVarUInt(DBMS_VERSION_MINOR, *out);
writeVarUInt(ClickHouseRevision::get(), *out);
if (client_revision >= DBMS_MIN_REVISION_WITH_SERVER_TIMEZONE)
- {
writeStringBinary(DateLUT::instance().getTimeZone(), *out);
- }
if (client_revision >= DBMS_MIN_REVISION_WITH_SERVER_DISPLAY_NAME)
- {
writeStringBinary(server_display_name, *out);
- }
+ if (client_revision >= DBMS_MIN_REVISION_WITH_VERSION_PATCH)
+ writeVarUInt(DBMS_VERSION_PATCH, *out);
out->next();
}
@@ -598,6 +597,7 @@ void TCPHandler::receiveQuery()
client_info.client_name = client_name;
client_info.client_version_major = client_version_major;
client_info.client_version_minor = client_version_minor;
+ client_info.client_version_patch = client_version_patch;
client_info.client_revision = client_revision;
}
diff --git a/dbms/programs/server/TCPHandler.h b/dbms/programs/server/TCPHandler.h
index e01987d3bbd..af122513cf7 100644
--- a/dbms/programs/server/TCPHandler.h
+++ b/dbms/programs/server/TCPHandler.h
@@ -98,6 +98,7 @@ private:
String client_name;
UInt64 client_version_major = 0;
UInt64 client_version_minor = 0;
+ UInt64 client_version_patch = 0;
UInt64 client_revision = 0;
Context connection_context;
diff --git a/dbms/programs/server/config.xml b/dbms/programs/server/config.xml
index 7dd7a00517e..e461d49d522 100644
--- a/dbms/programs/server/config.xml
+++ b/dbms/programs/server/config.xml
@@ -322,10 +322,12 @@
+
diff --git a/dbms/src/AggregateFunctions/AggregateFunctionArray.cpp b/dbms/src/AggregateFunctions/AggregateFunctionArray.cpp
index f42c5b6d142..9cb7d03bf69 100644
--- a/dbms/src/AggregateFunctions/AggregateFunctionArray.cpp
+++ b/dbms/src/AggregateFunctions/AggregateFunctionArray.cpp
@@ -18,6 +18,9 @@ public:
DataTypes transformArguments(const DataTypes & arguments) const override
{
+ if (0 == arguments.size())
+ throw Exception("-Array aggregate functions require at least one argument", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
+
DataTypes nested_arguments;
for (const auto & type : arguments)
{
diff --git a/dbms/src/AggregateFunctions/AggregateFunctionBitwise.cpp b/dbms/src/AggregateFunctions/AggregateFunctionBitwise.cpp
index 762baf2451b..8c188bcbb8e 100644
--- a/dbms/src/AggregateFunctions/AggregateFunctionBitwise.cpp
+++ b/dbms/src/AggregateFunctions/AggregateFunctionBitwise.cpp
@@ -38,9 +38,9 @@ void registerAggregateFunctionsBitwise(AggregateFunctionFactory & factory)
factory.registerFunction("groupBitXor", createAggregateFunctionBitwise);
/// Aliases for compatibility with MySQL.
- factory.registerFunction("BIT_OR", createAggregateFunctionBitwise, AggregateFunctionFactory::CaseInsensitive);
- factory.registerFunction("BIT_AND", createAggregateFunctionBitwise, AggregateFunctionFactory::CaseInsensitive);
- factory.registerFunction("BIT_XOR", createAggregateFunctionBitwise, AggregateFunctionFactory::CaseInsensitive);
+ factory.registerAlias("BIT_OR", "groupBitOr", AggregateFunctionFactory::CaseInsensitive);
+ factory.registerAlias("BIT_AND", "groupBitAnd", AggregateFunctionFactory::CaseInsensitive);
+ factory.registerAlias("BIT_XOR", "groupBitXor", AggregateFunctionFactory::CaseInsensitive);
}
}
diff --git a/dbms/src/AggregateFunctions/AggregateFunctionCombinatorFactory.h b/dbms/src/AggregateFunctions/AggregateFunctionCombinatorFactory.h
index 4c70cc6c068..579951cecb1 100644
--- a/dbms/src/AggregateFunctions/AggregateFunctionCombinatorFactory.h
+++ b/dbms/src/AggregateFunctions/AggregateFunctionCombinatorFactory.h
@@ -15,6 +15,10 @@ namespace DB
*/
class AggregateFunctionCombinatorFactory final: public ext::singleton
{
+private:
+ using Dict = std::unordered_map;
+ Dict dict;
+
public:
/// Not thread safe. You must register before using tryGet.
void registerCombinator(const AggregateFunctionCombinatorPtr & value);
@@ -22,8 +26,10 @@ public:
/// Example: if the name is 'avgIf', it will return combinator -If.
AggregateFunctionCombinatorPtr tryFindSuffix(const std::string & name) const;
-private:
- std::unordered_map dict;
+ const Dict & getAllAggregateFunctionCombinators() const
+ {
+ return dict;
+ }
};
}
diff --git a/dbms/src/AggregateFunctions/AggregateFunctionFactory.cpp b/dbms/src/AggregateFunctions/AggregateFunctionFactory.cpp
index 90109ff04c5..7876f0dcffb 100644
--- a/dbms/src/AggregateFunctions/AggregateFunctionFactory.cpp
+++ b/dbms/src/AggregateFunctions/AggregateFunctionFactory.cpp
@@ -95,11 +95,12 @@ AggregateFunctionPtr AggregateFunctionFactory::get(
AggregateFunctionPtr AggregateFunctionFactory::getImpl(
- const String & name,
+ const String & name_param,
const DataTypes & argument_types,
const Array & parameters,
int recursion_level) const
{
+ String name = getAliasToOrName(name_param);
/// Find by exact match.
auto it = aggregate_functions.find(name);
if (it != aggregate_functions.end())
@@ -120,8 +121,8 @@ AggregateFunctionPtr AggregateFunctionFactory::getImpl(
if (AggregateFunctionCombinatorPtr combinator = AggregateFunctionCombinatorFactory::instance().tryFindSuffix(name))
{
- if (combinator->getName() == "Null")
- throw Exception("Aggregate function combinator 'Null' is only for internal usage", ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION);
+ if (combinator->isForInternalUsageOnly())
+ throw Exception("Aggregate function combinator '" + combinator->getName() + "' is only for internal usage", ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION);
String nested_name = name.substr(0, name.size() - combinator->getName().size());
DataTypes nested_types = combinator->transformArguments(argument_types);
@@ -143,10 +144,11 @@ AggregateFunctionPtr AggregateFunctionFactory::tryGet(const String & name, const
bool AggregateFunctionFactory::isAggregateFunctionName(const String & name, int recursion_level) const
{
- if (aggregate_functions.count(name))
+ if (aggregate_functions.count(name) || isAlias(name))
return true;
- if (recursion_level == 0 && case_insensitive_aggregate_functions.count(Poco::toLower(name)))
+ String name_lowercase = Poco::toLower(name);
+ if (recursion_level == 0 && (case_insensitive_aggregate_functions.count(name_lowercase) || isAlias(name_lowercase)))
return true;
if (AggregateFunctionCombinatorPtr combinator = AggregateFunctionCombinatorFactory::instance().tryFindSuffix(name))
diff --git a/dbms/src/AggregateFunctions/AggregateFunctionFactory.h b/dbms/src/AggregateFunctions/AggregateFunctionFactory.h
index bc36e76c11f..92598e52509 100644
--- a/dbms/src/AggregateFunctions/AggregateFunctionFactory.h
+++ b/dbms/src/AggregateFunctions/AggregateFunctionFactory.h
@@ -1,6 +1,7 @@
#pragma once
#include
+#include
#include
@@ -20,27 +21,18 @@ class IDataType;
using DataTypePtr = std::shared_ptr;
using DataTypes = std::vector;
+/** Creator have arguments: name of aggregate function, types of arguments, values of parameters.
+ * Parameters are for "parametric" aggregate functions.
+ * For example, in quantileWeighted(0.9)(x, weight), 0.9 is "parameter" and x, weight are "arguments".
+ */
+using AggregateFunctionCreator = std::function;
+
/** Creates an aggregate function by name.
*/
-class AggregateFunctionFactory final : public ext::singleton
+class AggregateFunctionFactory final : public ext::singleton, public IFactoryWithAliases
{
- friend class StorageSystemFunctions;
-
public:
- /** Creator have arguments: name of aggregate function, types of arguments, values of parameters.
- * Parameters are for "parametric" aggregate functions.
- * For example, in quantileWeighted(0.9)(x, weight), 0.9 is "parameter" and x, weight are "arguments".
- */
- using Creator = std::function;
-
- /// For compatibility with SQL, it's possible to specify that certain aggregate function name is case insensitive.
- enum CaseSensitiveness
- {
- CaseSensitive,
- CaseInsensitive
- };
-
/// Register a function by its name.
/// No locking, you must register all functions before usage of get.
void registerFunction(
@@ -77,6 +69,13 @@ private:
/// Case insensitive aggregate functions will be additionally added here with lowercased name.
AggregateFunctions case_insensitive_aggregate_functions;
+
+ const AggregateFunctions & getCreatorMap() const override { return aggregate_functions; }
+
+ const AggregateFunctions & getCaseInsensitiveCreatorMap() const override { return case_insensitive_aggregate_functions; }
+
+ String getFactoryName() const override { return "AggregateFunctionFactory"; }
+
};
}
diff --git a/dbms/src/AggregateFunctions/AggregateFunctionMinMaxAny.h b/dbms/src/AggregateFunctions/AggregateFunctionMinMaxAny.h
index 4b92a6231fe..322307c2bcf 100644
--- a/dbms/src/AggregateFunctions/AggregateFunctionMinMaxAny.h
+++ b/dbms/src/AggregateFunctions/AggregateFunctionMinMaxAny.h
@@ -646,7 +646,7 @@ struct AggregateFunctionAnyHeavyData : Data
}
else
{
- if (counter < to.counter)
+ if ((!this->has() && to.has()) || counter < to.counter)
{
this->change(to, arena);
return true;
diff --git a/dbms/src/AggregateFunctions/AggregateFunctionNull.cpp b/dbms/src/AggregateFunctions/AggregateFunctionNull.cpp
index 46a46a2370a..6ce7d94d970 100644
--- a/dbms/src/AggregateFunctions/AggregateFunctionNull.cpp
+++ b/dbms/src/AggregateFunctions/AggregateFunctionNull.cpp
@@ -18,6 +18,8 @@ class AggregateFunctionCombinatorNull final : public IAggregateFunctionCombinato
public:
String getName() const override { return "Null"; }
+ bool isForInternalUsageOnly() const override { return true; }
+
DataTypes transformArguments(const DataTypes & arguments) const override
{
size_t size = arguments.size();
diff --git a/dbms/src/AggregateFunctions/AggregateFunctionQuantile.cpp b/dbms/src/AggregateFunctions/AggregateFunctionQuantile.cpp
index 250ee422e8b..62455af6353 100644
--- a/dbms/src/AggregateFunctions/AggregateFunctionQuantile.cpp
+++ b/dbms/src/AggregateFunctions/AggregateFunctionQuantile.cpp
@@ -93,30 +93,14 @@ void registerAggregateFunctionsQuantile(AggregateFunctionFactory & factory)
createAggregateFunctionQuantile);
/// 'median' is an alias for 'quantile'
-
- factory.registerFunction("median",
- createAggregateFunctionQuantile);
-
- factory.registerFunction("medianDeterministic",
- createAggregateFunctionQuantile);
-
- factory.registerFunction("medianExact",
- createAggregateFunctionQuantile);
-
- factory.registerFunction("medianExactWeighted",
- createAggregateFunctionQuantile);
-
- factory.registerFunction("medianTiming",
- createAggregateFunctionQuantile);
-
- factory.registerFunction("medianTimingWeighted",
- createAggregateFunctionQuantile);
-
- factory.registerFunction("medianTDigest",
- createAggregateFunctionQuantile);
-
- factory.registerFunction("medianTDigestWeighted",
- createAggregateFunctionQuantile);
+ factory.registerAlias("median", NameQuantile::name);
+ factory.registerAlias("medianDeterministic", NameQuantileDeterministic::name);
+ factory.registerAlias("medianExact", NameQuantileExact::name);
+ factory.registerAlias("medianExactWeighted", NameQuantileExactWeighted::name);
+ factory.registerAlias("medianTiming", NameQuantileTiming::name);
+ factory.registerAlias("medianTimingWeighted", NameQuantileTimingWeighted::name);
+ factory.registerAlias("medianTDigest", NameQuantileTDigest::name);
+ factory.registerAlias("medianTDigestWeighted", NameQuantileTDigestWeighted::name);
}
}
diff --git a/dbms/src/AggregateFunctions/AggregateFunctionWindowFunnel.h b/dbms/src/AggregateFunctions/AggregateFunctionWindowFunnel.h
index 4ad0400d160..b62755ef00c 100644
--- a/dbms/src/AggregateFunctions/AggregateFunctionWindowFunnel.h
+++ b/dbms/src/AggregateFunctions/AggregateFunctionWindowFunnel.h
@@ -116,7 +116,7 @@ struct AggregateFunctionWindowFunnelData
/// TODO Protection against huge size
events_list.clear();
- events_list.resize(size);
+ events_list.reserve(size);
UInt32 timestamp;
UInt8 event;
diff --git a/dbms/src/AggregateFunctions/AggregateFunctionsStatisticsSimple.cpp b/dbms/src/AggregateFunctions/AggregateFunctionsStatisticsSimple.cpp
index 089ea59cd79..c42372187bc 100644
--- a/dbms/src/AggregateFunctions/AggregateFunctionsStatisticsSimple.cpp
+++ b/dbms/src/AggregateFunctions/AggregateFunctionsStatisticsSimple.cpp
@@ -56,12 +56,12 @@ void registerAggregateFunctionsStatisticsSimple(AggregateFunctionFactory & facto
factory.registerFunction("corr", createAggregateFunctionStatisticsBinary, AggregateFunctionFactory::CaseInsensitive);
/// Synonims for compatibility.
- factory.registerFunction("VAR_SAMP", createAggregateFunctionStatisticsUnary, AggregateFunctionFactory::CaseInsensitive);
- factory.registerFunction("VAR_POP", createAggregateFunctionStatisticsUnary, AggregateFunctionFactory::CaseInsensitive);
- factory.registerFunction("STDDEV_SAMP", createAggregateFunctionStatisticsUnary, AggregateFunctionFactory::CaseInsensitive);
- factory.registerFunction("STDDEV_POP", createAggregateFunctionStatisticsUnary, AggregateFunctionFactory::CaseInsensitive);
- factory.registerFunction("COVAR_SAMP", createAggregateFunctionStatisticsBinary, AggregateFunctionFactory::CaseInsensitive);
- factory.registerFunction("COVAR_POP", createAggregateFunctionStatisticsBinary, AggregateFunctionFactory::CaseInsensitive);
+ factory.registerAlias("VAR_SAMP", "varSamp", AggregateFunctionFactory::CaseInsensitive);
+ factory.registerAlias("VAR_POP", "varPop", AggregateFunctionFactory::CaseInsensitive);
+ factory.registerAlias("STDDEV_SAMP", "stddevSamp", AggregateFunctionFactory::CaseInsensitive);
+ factory.registerAlias("STDDEV_POP", "stddevPop", AggregateFunctionFactory::CaseInsensitive);
+ factory.registerAlias("COVAR_SAMP", "covarSamp", AggregateFunctionFactory::CaseInsensitive);
+ factory.registerAlias("COVAR_POP", "covarPop", AggregateFunctionFactory::CaseInsensitive);
}
}
diff --git a/dbms/src/AggregateFunctions/IAggregateFunctionCombinator.h b/dbms/src/AggregateFunctions/IAggregateFunctionCombinator.h
index ba28026b1cd..0ac9a3d41cd 100644
--- a/dbms/src/AggregateFunctions/IAggregateFunctionCombinator.h
+++ b/dbms/src/AggregateFunctions/IAggregateFunctionCombinator.h
@@ -32,6 +32,8 @@ class IAggregateFunctionCombinator
public:
virtual String getName() const = 0;
+ virtual bool isForInternalUsageOnly() const { return false; }
+
/** From the arguments for combined function (ex: UInt64, UInt8 for sumIf),
* get the arguments for nested function (ex: UInt64 for sum).
* If arguments are not suitable for combined function, throw an exception.
diff --git a/dbms/src/Client/Connection.cpp b/dbms/src/Client/Connection.cpp
index b847d905054..affd89b1c28 100644
--- a/dbms/src/Client/Connection.cpp
+++ b/dbms/src/Client/Connection.cpp
@@ -89,7 +89,7 @@ void Connection::connect()
LOG_TRACE(log_wrapper.get(), "Connected to " << server_name
<< " server version " << server_version_major
<< "." << server_version_minor
- << "." << server_revision
+ << "." << server_version_patch
<< ".");
}
catch (Poco::Net::NetException & e)
@@ -150,6 +150,7 @@ void Connection::sendHello()
writeStringBinary((DBMS_NAME " ") + client_name, *out);
writeVarUInt(DBMS_VERSION_MAJOR, *out);
writeVarUInt(DBMS_VERSION_MINOR, *out);
+ // NOTE For backward compatibility of the protocol, client cannot send its version_patch.
writeVarUInt(ClickHouseRevision::get(), *out);
writeStringBinary(default_database, *out);
writeStringBinary(user, *out);
@@ -174,13 +175,13 @@ void Connection::receiveHello()
readVarUInt(server_version_minor, *in);
readVarUInt(server_revision, *in);
if (server_revision >= DBMS_MIN_REVISION_WITH_SERVER_TIMEZONE)
- {
readStringBinary(server_timezone, *in);
- }
if (server_revision >= DBMS_MIN_REVISION_WITH_SERVER_DISPLAY_NAME)
- {
readStringBinary(server_display_name, *in);
- }
+ if (server_revision >= DBMS_MIN_REVISION_WITH_VERSION_PATCH)
+ readVarUInt(server_version_patch, *in);
+ else
+ server_version_patch = server_revision;
}
else if (packet_type == Protocol::Server::Exception)
receiveException()->rethrow();
@@ -217,7 +218,7 @@ UInt16 Connection::getPort() const
return port;
}
-void Connection::getServerVersion(String & name, UInt64 & version_major, UInt64 & version_minor, UInt64 & revision)
+void Connection::getServerVersion(String & name, UInt64 & version_major, UInt64 & version_minor, UInt64 & version_patch, UInt64 & revision)
{
if (!connected)
connect();
@@ -225,6 +226,7 @@ void Connection::getServerVersion(String & name, UInt64 & version_major, UInt64
name = server_name;
version_major = server_version_major;
version_minor = server_version_minor;
+ version_patch = server_version_patch;
revision = server_revision;
}
diff --git a/dbms/src/Client/Connection.h b/dbms/src/Client/Connection.h
index 2da794b8434..dabb50b53a9 100644
--- a/dbms/src/Client/Connection.h
+++ b/dbms/src/Client/Connection.h
@@ -104,7 +104,7 @@ public:
/// Change default database. Changes will take effect on next reconnect.
void setDefaultDatabase(const String & database);
- void getServerVersion(String & name, UInt64 & version_major, UInt64 & version_minor, UInt64 & revision);
+ void getServerVersion(String & name, UInt64 & version_major, UInt64 & version_minor, UInt64 & version_patch, UInt64 & revision);
const String & getServerTimezone();
const String & getServerDisplayName();
@@ -187,6 +187,7 @@ private:
String server_name;
UInt64 server_version_major = 0;
UInt64 server_version_minor = 0;
+ UInt64 server_version_patch = 0;
UInt64 server_revision = 0;
String server_timezone;
String server_display_name;
diff --git a/dbms/src/Client/ConnectionPoolWithFailover.cpp b/dbms/src/Client/ConnectionPoolWithFailover.cpp
index ee8c3607c43..73469fcf53f 100644
--- a/dbms/src/Client/ConnectionPoolWithFailover.cpp
+++ b/dbms/src/Client/ConnectionPoolWithFailover.cpp
@@ -83,6 +83,16 @@ std::vector ConnectionPoolWithFailover::getMany(const Se
return entries;
}
+std::vector ConnectionPoolWithFailover::getManyForTableFunction(const Settings * settings, PoolMode pool_mode)
+{
+ TryGetEntryFunc try_get_entry = [&](NestedPool & pool, std::string & fail_message)
+ {
+ return tryGetEntry(pool, fail_message, settings);
+ };
+
+ return getManyImpl(settings, pool_mode, try_get_entry);
+}
+
std::vector ConnectionPoolWithFailover::getManyChecked(
const Settings * settings, PoolMode pool_mode, const QualifiedTableName & table_to_check)
{
@@ -90,6 +100,7 @@ std::vector ConnectionPoolWithFailover::g
{
return tryGetEntry(pool, fail_message, settings, &table_to_check);
};
+
return getManyImpl(settings, pool_mode, try_get_entry);
}
@@ -145,9 +156,10 @@ ConnectionPoolWithFailover::tryGetEntry(
String server_name;
UInt64 server_version_major;
UInt64 server_version_minor;
+ UInt64 server_version_patch;
UInt64 server_revision;
if (table_to_check)
- result.entry->getServerVersion(server_name, server_version_major, server_version_minor, server_revision);
+ result.entry->getServerVersion(server_name, server_version_major, server_version_minor, server_version_patch, server_revision);
if (!table_to_check || server_revision < DBMS_MIN_REVISION_WITH_TABLES_STATUS)
{
diff --git a/dbms/src/Client/ConnectionPoolWithFailover.h b/dbms/src/Client/ConnectionPoolWithFailover.h
index b61fa03d711..62ca75859ba 100644
--- a/dbms/src/Client/ConnectionPoolWithFailover.h
+++ b/dbms/src/Client/ConnectionPoolWithFailover.h
@@ -47,6 +47,9 @@ public:
*/
std::vector getMany(const Settings * settings, PoolMode pool_mode);
+ /// The same as getMany(), but return std::vector.
+ std::vector getManyForTableFunction(const Settings * settings, PoolMode pool_mode);
+
using Base = PoolWithFailoverBase;
using TryResult = Base::TryResult;
diff --git a/dbms/src/Columns/Collator.cpp b/dbms/src/Columns/Collator.cpp
index b6cea96ed2f..aaf917fb93d 100644
--- a/dbms/src/Columns/Collator.cpp
+++ b/dbms/src/Columns/Collator.cpp
@@ -87,3 +87,14 @@ const std::string & Collator::getLocale() const
{
return locale;
}
+
+std::vector Collator::getAvailableCollations()
+{
+ std::vector result;
+#if USE_ICU
+ size_t available_locales_count = ucol_countAvailable();
+ for (size_t i = 0; i < available_locales_count; ++i)
+ result.push_back(ucol_getAvailable(i));
+#endif
+ return result;
+}
diff --git a/dbms/src/Columns/Collator.h b/dbms/src/Columns/Collator.h
index 53341fb1aeb..0bafe6b1dba 100644
--- a/dbms/src/Columns/Collator.h
+++ b/dbms/src/Columns/Collator.h
@@ -1,6 +1,7 @@
#pragma once
#include
+#include
#include
struct UCollator;
@@ -15,6 +16,8 @@ public:
const std::string & getLocale() const;
+ static std::vector getAvailableCollations();
+
private:
std::string locale;
UCollator * collator;
diff --git a/dbms/src/Common/BackgroundSchedulePool.cpp b/dbms/src/Common/BackgroundSchedulePool.cpp
index 84eecdad7ff..9556c9a037b 100644
--- a/dbms/src/Common/BackgroundSchedulePool.cpp
+++ b/dbms/src/Common/BackgroundSchedulePool.cpp
@@ -128,7 +128,8 @@ void BackgroundSchedulePool::TaskInfo::execute()
zkutil::WatchCallback BackgroundSchedulePool::TaskInfo::getWatchCallback()
{
- return [t=shared_from_this()](const ZooKeeperImpl::ZooKeeper::WatchResponse &) {
+ return [t = shared_from_this()](const ZooKeeperImpl::ZooKeeper::WatchResponse &)
+ {
t->schedule();
};
}
diff --git a/dbms/src/Common/Config/ConfigProcessor.cpp b/dbms/src/Common/Config/ConfigProcessor.cpp
index 1e0cb91340b..95189affce8 100644
--- a/dbms/src/Common/Config/ConfigProcessor.cpp
+++ b/dbms/src/Common/Config/ConfigProcessor.cpp
@@ -2,6 +2,7 @@
#include
#include
+#include
#include
#include
#include
@@ -103,7 +104,9 @@ static ElementIdentifier getElementIdentifier(Node * element)
{
const Node * node = attrs->item(i);
std::string name = node->nodeName();
- if (name == "replace" || name == "remove" || name == "incl" || name == "from_zk")
+ auto subst_name_pos = std::find(ConfigProcessor::SUBSTITUTION_ATTRS.begin(), ConfigProcessor::SUBSTITUTION_ATTRS.end(), name);
+ if (name == "replace" || name == "remove" ||
+ subst_name_pos != ConfigProcessor::SUBSTITUTION_ATTRS.end())
continue;
std::string value = node->nodeValue();
attrs_kv.push_back(std::make_pair(name, value));
@@ -267,12 +270,18 @@ void ConfigProcessor::doIncludesRecursive(
return;
}
+ std::map attr_nodes;
NamedNodeMapPtr attributes = node->attributes();
- const Node * incl_attribute = attributes->getNamedItem("incl");
- const Node * from_zk_attribute = attributes->getNamedItem("from_zk");
+ size_t substs_count = 0;
+ for (const auto & attr_name : SUBSTITUTION_ATTRS)
+ {
+ auto subst = attributes->getNamedItem(attr_name);
+ attr_nodes[attr_name] = subst;
+ substs_count += static_cast(subst == nullptr);
+ }
- if (incl_attribute && from_zk_attribute)
- throw Poco::Exception("both incl and from_zk attributes set for element <" + node->nodeName() + ">");
+ if (substs_count < SUBSTITUTION_ATTRS.size() - 1) /// only one substitution is allowed
+ throw Poco::Exception("several substitutions attributes set for element <" + node->nodeName() + ">");
/// Replace the original contents, not add to it.
bool replace = attributes->getNamedItem("replace");
@@ -296,8 +305,8 @@ void ConfigProcessor::doIncludesRecursive(
{
Element & element = dynamic_cast(*node);
- element.removeAttribute("incl");
- element.removeAttribute("from_zk");
+ for (const auto & attr_name : SUBSTITUTION_ATTRS)
+ element.removeAttribute(attr_name);
if (replace)
{
@@ -324,16 +333,19 @@ void ConfigProcessor::doIncludesRecursive(
}
};
- auto get_incl_node = [&](const std::string & name)
+ if (attr_nodes["incl"]) // we have include subst
{
- return include_from ? include_from->getNodeByPath("yandex/" + name) : nullptr;
- };
- if (incl_attribute)
- process_include(incl_attribute, get_incl_node, "Include not found: ");
+ auto get_incl_node = [&](const std::string & name)
+ {
+ return include_from ? include_from->getNodeByPath("yandex/" + name) : nullptr;
+ };
- if (from_zk_attribute)
+ process_include(attr_nodes["incl"], get_incl_node, "Include not found: ");
+ }
+
+ if (attr_nodes["from_zk"]) /// we have zookeeper subst
{
- contributing_zk_paths.insert(from_zk_attribute->getNodeValue());
+ contributing_zk_paths.insert(attr_nodes["from_zk"]->getNodeValue());
if (zk_node_cache)
{
@@ -349,10 +361,27 @@ void ConfigProcessor::doIncludesRecursive(
return getRootNode(zk_document.get());
};
- process_include(from_zk_attribute, get_zk_node, "Could not get ZooKeeper node: ");
+ process_include(attr_nodes["from_zk"], get_zk_node, "Could not get ZooKeeper node: ");
}
}
+ if (attr_nodes["from_env"]) /// we have env subst
+ {
+ XMLDocumentPtr env_document;
+ auto get_env_node = [&](const std::string & name) -> const Node *
+ {
+ const char * env_val = std::getenv(name.c_str());
+ if (env_val == nullptr)
+ return nullptr;
+
+ env_document = dom_parser.parseString("" + std::string{env_val} + "");
+
+ return getRootNode(env_document.get());
+ };
+
+ process_include(attr_nodes["from_env"], get_env_node, "Env variable is not set: ");
+ }
+
if (included_something)
doIncludesRecursive(config, include_from, node, zk_node_cache, contributing_zk_paths);
else
@@ -377,9 +406,6 @@ ConfigProcessor::Files ConfigProcessor::getConfigMergeFiles(const std::string &
/// Add path_to_config/conf.d dir
merge_dir_path.setBaseName("conf");
merge_dirs.insert(merge_dir_path.toString());
- /// Add path_to_config/config.d dir
- merge_dir_path.setBaseName("config");
- merge_dirs.insert(merge_dir_path.toString());
for (const std::string & merge_dir_name : merge_dirs)
{
diff --git a/dbms/src/Common/Config/ConfigProcessor.h b/dbms/src/Common/Config/ConfigProcessor.h
index 8c9048bb102..8663ecb682f 100644
--- a/dbms/src/Common/Config/ConfigProcessor.h
+++ b/dbms/src/Common/Config/ConfigProcessor.h
@@ -95,6 +95,8 @@ public:
/// Is the file named as result of config preprocessing, not as original files.
static bool isPreprocessedFile(const std::string & config_path);
+ static inline const auto SUBSTITUTION_ATTRS = {"incl", "from_zk", "from_env"};
+
private:
const std::string path;
const std::string preprocessed_path;
diff --git a/dbms/src/Common/ErrorCodes.cpp b/dbms/src/Common/ErrorCodes.cpp
index a1662563a1f..e719f8be4b3 100644
--- a/dbms/src/Common/ErrorCodes.cpp
+++ b/dbms/src/Common/ErrorCodes.cpp
@@ -377,7 +377,9 @@ namespace ErrorCodes
extern const int CANNOT_STAT = 400;
extern const int FEATURE_IS_NOT_ENABLED_AT_BUILD_TIME = 401;
extern const int CANNOT_IOSETUP = 402;
-
+ extern const int INVALID_JOIN_ON_EXPRESSION = 403;
+ extern const int BAD_ODBC_CONNECTION_STRING = 404;
+ extern const int PARTITION_SIZE_EXCEEDS_MAX_DROP_SIZE_LIMIT = 405;
extern const int KEEPER_EXCEPTION = 999;
extern const int POCO_EXCEPTION = 1000;
diff --git a/dbms/src/Common/FieldVisitors.cpp b/dbms/src/Common/FieldVisitors.cpp
index 3132a7412ca..62b7667d936 100644
--- a/dbms/src/Common/FieldVisitors.cpp
+++ b/dbms/src/Common/FieldVisitors.cpp
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
#include
#include
@@ -35,6 +36,13 @@ String FieldVisitorDump::operator() (const UInt64 & x) const { return formatQuot
String FieldVisitorDump::operator() (const Int64 & x) const { return formatQuotedWithPrefix(x, "Int64_"); }
String FieldVisitorDump::operator() (const Float64 & x) const { return formatQuotedWithPrefix(x, "Float64_"); }
+String FieldVisitorDump::operator() (const UInt128 & x) const
+{
+ WriteBufferFromOwnString wb;
+ wb << "UInt128_" << x.low << "_" << x.high;
+ return wb.str();
+
+}
String FieldVisitorDump::operator() (const String & x) const
{
@@ -47,14 +55,14 @@ String FieldVisitorDump::operator() (const Array & x) const
{
WriteBufferFromOwnString wb;
- wb.write("Array_[", 7);
+ wb << "Array_[";
for (auto it = x.begin(); it != x.end(); ++it)
{
if (it != x.begin())
- wb.write(", ", 2);
- writeString(applyVisitor(*this, *it), wb);
+ wb << ", ";
+ wb << applyVisitor(*this, *it);
}
- writeChar(']', wb);
+ wb << ']';
return wb.str();
}
@@ -64,14 +72,14 @@ String FieldVisitorDump::operator() (const Tuple & x_def) const
auto & x = x_def.toUnderType();
WriteBufferFromOwnString wb;
- wb.write("Tuple_(", 7);
+ wb << "Tuple_(";
for (auto it = x.begin(); it != x.end(); ++it)
{
if (it != x.begin())
- wb.write(", ", 2);
- writeString(applyVisitor(*this, *it), wb);
+ wb << ", ";
+ wb << applyVisitor(*this, *it);
}
- writeChar(')', wb);
+ wb << ')';
return wb.str();
}
@@ -105,19 +113,24 @@ String FieldVisitorToString::operator() (const Int64 & x) const { return formatQ
String FieldVisitorToString::operator() (const Float64 & x) const { return formatFloat(x); }
String FieldVisitorToString::operator() (const String & x) const { return formatQuoted(x); }
+String FieldVisitorToString::operator() (const UInt128 & x) const
+{
+ /// Dummy implementation. There is no UInt128 literals in SQL.
+ return FieldVisitorDump()(x);
+}
String FieldVisitorToString::operator() (const Array & x) const
{
WriteBufferFromOwnString wb;
- writeChar('[', wb);
+ wb << '[';
for (Array::const_iterator it = x.begin(); it != x.end(); ++it)
{
if (it != x.begin())
wb.write(", ", 2);
- writeString(applyVisitor(*this, *it), wb);
+ wb << applyVisitor(*this, *it);
}
- writeChar(']', wb);
+ wb << ']';
return wb.str();
}
@@ -127,14 +140,14 @@ String FieldVisitorToString::operator() (const Tuple & x_def) const
auto & x = x_def.toUnderType();
WriteBufferFromOwnString wb;
- writeChar('(', wb);
+ wb << '(';
for (auto it = x.begin(); it != x.end(); ++it)
{
if (it != x.begin())
- wb.write(", ", 2);
- writeString(applyVisitor(*this, *it), wb);
+ wb << ", ";
+ wb << applyVisitor(*this, *it);
}
- writeChar(')', wb);
+ wb << ')';
return wb.str();
}
@@ -155,6 +168,13 @@ void FieldVisitorHash::operator() (const UInt64 & x) const
hash.update(x);
}
+void FieldVisitorHash::operator() (const UInt128 & x) const
+{
+ UInt8 type = Field::Types::UInt128;
+ hash.update(type);
+ hash.update(x);
+}
+
void FieldVisitorHash::operator() (const Int64 & x) const
{
UInt8 type = Field::Types::Int64;
diff --git a/dbms/src/Common/FieldVisitors.h b/dbms/src/Common/FieldVisitors.h
index b59c6a47aa7..8abf75dbc64 100644
--- a/dbms/src/Common/FieldVisitors.h
+++ b/dbms/src/Common/FieldVisitors.h
@@ -38,6 +38,7 @@ typename std::decay_t::ResultType applyVisitor(Visitor && visitor, F &&
{
case Field::Types::Null: return visitor(field.template get());
case Field::Types::UInt64: return visitor(field.template get());
+ case Field::Types::UInt128: return visitor(field.template get());
case Field::Types::Int64: return visitor(field.template get());
case Field::Types::Float64: return visitor(field.template get());
case Field::Types::String: return visitor(field.template get());
@@ -57,6 +58,7 @@ static typename std::decay_t::ResultType applyBinaryVisitorImpl(Visitor
{
case Field::Types::Null: return visitor(field1, field2.template get());
case Field::Types::UInt64: return visitor(field1, field2.template get());
+ case Field::Types::UInt128: return visitor(field1, field2.template get());
case Field::Types::Int64: return visitor(field1, field2.template get());
case Field::Types::Float64: return visitor(field1, field2.template get());
case Field::Types::String: return visitor(field1, field2.template get());
@@ -79,6 +81,9 @@ typename std::decay_t::ResultType applyVisitor(Visitor && visitor, F1 &
case Field::Types::UInt64:
return applyBinaryVisitorImpl(
std::forward(visitor), field1.template get(), std::forward(field2));
+ case Field::Types::UInt128:
+ return applyBinaryVisitorImpl(
+ std::forward(visitor), field1.template get(), std::forward(field2));
case Field::Types::Int64:
return applyBinaryVisitorImpl(
std::forward(visitor), field1.template get(), std::forward(field2));
@@ -107,6 +112,7 @@ class FieldVisitorToString : public StaticVisitor
public:
String operator() (const Null & x) const;
String operator() (const UInt64 & x) const;
+ String operator() (const UInt128 & x) const;
String operator() (const Int64 & x) const;
String operator() (const Float64 & x) const;
String operator() (const String & x) const;
@@ -121,6 +127,7 @@ class FieldVisitorDump : public StaticVisitor
public:
String operator() (const Null & x) const;
String operator() (const UInt64 & x) const;
+ String operator() (const UInt128 & x) const;
String operator() (const Int64 & x) const;
String operator() (const Float64 & x) const;
String operator() (const String & x) const;
@@ -157,6 +164,11 @@ public:
T operator() (const UInt64 & x) const { return x; }
T operator() (const Int64 & x) const { return x; }
T operator() (const Float64 & x) const { return x; }
+
+ T operator() (const UInt128 &) const
+ {
+ throw Exception("Cannot convert UInt128 to " + demangle(typeid(T).name()), ErrorCodes::CANNOT_CONVERT_TYPE);
+ }
};
@@ -170,6 +182,7 @@ public:
void operator() (const Null & x) const;
void operator() (const UInt64 & x) const;
+ void operator() (const UInt128 & x) const;
void operator() (const Int64 & x) const;
void operator() (const Float64 & x) const;
void operator() (const String & x) const;
@@ -180,44 +193,60 @@ public:
/** More precise comparison, used for index.
* Differs from Field::operator< and Field::operator== in that it also compares values of different types.
* Comparison rules are same as in FunctionsComparison (to be consistent with expression evaluation in query).
+ *
+ * TODO Comparisons of UInt128 with different type are incorrect.
*/
class FieldVisitorAccurateEquals : public StaticVisitor
{
public:
bool operator() (const Null &, const Null &) const { return true; }
bool operator() (const Null &, const UInt64 &) const { return false; }
+ bool operator() (const Null &, const UInt128 &) const { return false; }
bool operator() (const Null &, const Int64 &) const { return false; }
bool operator() (const Null &, const Float64 &) const { return false; }
bool operator() (const Null &, const String &) const { return false; }
bool operator() (const Null &, const Array &) const { return false; }
bool operator() (const Null &, const Tuple &) const { return false; }
- bool operator() (const UInt64 &, const Null &) const { return false; }
+ bool operator() (const UInt64 &, const Null &) const { return false; }
bool operator() (const UInt64 & l, const UInt64 & r) const { return l == r; }
+ bool operator() (const UInt64 &, const UInt128) const { return true; }
bool operator() (const UInt64 & l, const Int64 & r) const { return accurate::equalsOp(l, r); }
bool operator() (const UInt64 & l, const Float64 & r) const { return accurate::equalsOp(l, r); }
- bool operator() (const UInt64 &, const String &) const { return false; }
- bool operator() (const UInt64 &, const Array &) const { return false; }
- bool operator() (const UInt64 &, const Tuple &) const { return false; }
+ bool operator() (const UInt64 &, const String &) const { return false; }
+ bool operator() (const UInt64 &, const Array &) const { return false; }
+ bool operator() (const UInt64 &, const Tuple &) const { return false; }
- bool operator() (const Int64 &, const Null &) const { return false; }
+ bool operator() (const UInt128 &, const Null &) const { return false; }
+ bool operator() (const UInt128 &, const UInt64) const { return false; }
+ bool operator() (const UInt128 & l, const UInt128 & r) const { return l == r; }
+ bool operator() (const UInt128 &, const Int64) const { return false; }
+ bool operator() (const UInt128 &, const Float64) const { return false; }
+ bool operator() (const UInt128 &, const String &) const { return false; }
+ bool operator() (const UInt128 &, const Array &) const { return false; }
+ bool operator() (const UInt128 &, const Tuple &) const { return false; }
+
+ bool operator() (const Int64 &, const Null &) const { return false; }
bool operator() (const Int64 & l, const UInt64 & r) const { return accurate::equalsOp(l, r); }
+ bool operator() (const Int64 &, const UInt128) const { return false; }
bool operator() (const Int64 & l, const Int64 & r) const { return l == r; }
bool operator() (const Int64 & l, const Float64 & r) const { return accurate::equalsOp(l, r); }
- bool operator() (const Int64 &, const String &) const { return false; }
- bool operator() (const Int64 &, const Array &) const { return false; }
- bool operator() (const Int64 &, const Tuple &) const { return false; }
+ bool operator() (const Int64 &, const String &) const { return false; }
+ bool operator() (const Int64 &, const Array &) const { return false; }
+ bool operator() (const Int64 &, const Tuple &) const { return false; }
- bool operator() (const Float64 &, const Null &) const { return false; }
+ bool operator() (const Float64 &, const Null &) const { return false; }
bool operator() (const Float64 & l, const UInt64 & r) const { return accurate::equalsOp(l, r); }
+ bool operator() (const Float64 &, const UInt128) const { return false; }
bool operator() (const Float64 & l, const Int64 & r) const { return accurate::equalsOp(l, r); }
bool operator() (const Float64 & l, const Float64 & r) const { return l == r; }
- bool operator() (const Float64 &, const String &) const { return false; }
- bool operator() (const Float64 &, const Array &) const { return false; }
- bool operator() (const Float64 &, const Tuple &) const { return false; }
+ bool operator() (const Float64 &, const String &) const { return false; }
+ bool operator() (const Float64 &, const Array &) const { return false; }
+ bool operator() (const Float64 &, const Tuple &) const { return false; }
bool operator() (const String &, const Null &) const { return false; }
bool operator() (const String &, const UInt64 &) const { return false; }
+ bool operator() (const String &, const UInt128 &) const { return false; }
bool operator() (const String &, const Int64 &) const { return false; }
bool operator() (const String &, const Float64 &) const { return false; }
bool operator() (const String & l, const String & r) const { return l == r; }
@@ -226,6 +255,7 @@ public:
bool operator() (const Array &, const Null &) const { return false; }
bool operator() (const Array &, const UInt64 &) const { return false; }
+ bool operator() (const Array &, const UInt128 &) const { return false; }
bool operator() (const Array &, const Int64 &) const { return false; }
bool operator() (const Array &, const Float64 &) const { return false; }
bool operator() (const Array &, const String &) const { return false; }
@@ -234,6 +264,7 @@ public:
bool operator() (const Tuple &, const Null &) const { return false; }
bool operator() (const Tuple &, const UInt64 &) const { return false; }
+ bool operator() (const Tuple &, const UInt128 &) const { return false; }
bool operator() (const Tuple &, const Int64 &) const { return false; }
bool operator() (const Tuple &, const Float64 &) const { return false; }
bool operator() (const Tuple &, const String &) const { return false; }
@@ -247,45 +278,60 @@ public:
bool operator() (const Null &, const Null &) const { return false; }
bool operator() (const Null &, const UInt64 &) const { return true; }
bool operator() (const Null &, const Int64 &) const { return true; }
+ bool operator() (const Null &, const UInt128 &) const { return true; }
bool operator() (const Null &, const Float64 &) const { return true; }
bool operator() (const Null &, const String &) const { return true; }
bool operator() (const Null &, const Array &) const { return true; }
bool operator() (const Null &, const Tuple &) const { return true; }
- bool operator() (const UInt64 &, const Null &) const { return false; }
+ bool operator() (const UInt64 &, const Null &) const { return false; }
bool operator() (const UInt64 & l, const UInt64 & r) const { return l < r; }
+ bool operator() (const UInt64 &, const UInt128 &) const { return true; }
bool operator() (const UInt64 & l, const Int64 & r) const { return accurate::lessOp(l, r); }
bool operator() (const UInt64 & l, const Float64 & r) const { return accurate::lessOp(l, r); }
- bool operator() (const UInt64 &, const String &) const { return true; }
- bool operator() (const UInt64 &, const Array &) const { return true; }
- bool operator() (const UInt64 &, const Tuple &) const { return true; }
+ bool operator() (const UInt64 &, const String &) const { return true; }
+ bool operator() (const UInt64 &, const Array &) const { return true; }
+ bool operator() (const UInt64 &, const Tuple &) const { return true; }
- bool operator() (const Int64 &, const Null &) const { return false; }
+ bool operator() (const UInt128 &, const Null &) const { return false; }
+ bool operator() (const UInt128 &, const UInt64) const { return false; }
+ bool operator() (const UInt128 & l, const UInt128 & r) const { return l < r; }
+ bool operator() (const UInt128 &, const Int64) const { return false; }
+ bool operator() (const UInt128 &, const Float64) const { return false; }
+ bool operator() (const UInt128 &, const String &) const { return false; }
+ bool operator() (const UInt128 &, const Array &) const { return false; }
+ bool operator() (const UInt128 &, const Tuple &) const { return false; }
+
+ bool operator() (const Int64 &, const Null &) const { return false; }
bool operator() (const Int64 & l, const UInt64 & r) const { return accurate::lessOp(l, r); }
+ bool operator() (const Int64 &, const UInt128 &) const { return false; }
bool operator() (const Int64 & l, const Int64 & r) const { return l < r; }
bool operator() (const Int64 & l, const Float64 & r) const { return accurate::lessOp(l, r); }
- bool operator() (const Int64 &, const String &) const { return true; }
- bool operator() (const Int64 &, const Array &) const { return true; }
- bool operator() (const Int64 &, const Tuple &) const { return true; }
+ bool operator() (const Int64 &, const String &) const { return true; }
+ bool operator() (const Int64 &, const Array &) const { return true; }
+ bool operator() (const Int64 &, const Tuple &) const { return true; }
- bool operator() (const Float64 &, const Null &) const { return false; }
+ bool operator() (const Float64 &, const Null &) const { return false; }
bool operator() (const Float64 & l, const UInt64 & r) const { return accurate::lessOp(l, r); }
+ bool operator() (const Float64, const UInt128 &) const { return false; }
bool operator() (const Float64 & l, const Int64 & r) const { return accurate::lessOp(l, r); }
bool operator() (const Float64 & l, const Float64 & r) const { return l < r; }
- bool operator() (const Float64 &, const String &) const { return true; }
- bool operator() (const Float64 &, const Array &) const { return true; }
- bool operator() (const Float64 &, const Tuple &) const { return true; }
+ bool operator() (const Float64 &, const String &) const { return true; }
+ bool operator() (const Float64 &, const Array &) const { return true; }
+ bool operator() (const Float64 &, const Tuple &) const { return true; }
- bool operator() (const String &, const Null &) const { return false; }
- bool operator() (const String &, const UInt64 &) const { return false; }
- bool operator() (const String &, const Int64 &) const { return false; }
- bool operator() (const String &, const Float64 &) const { return false; }
+ bool operator() (const String &, const Null &) const { return false; }
+ bool operator() (const String &, const UInt64 &) const { return false; }
+ bool operator() (const String &, const UInt128 &) const { return false; }
+ bool operator() (const String &, const Int64 &) const { return false; }
+ bool operator() (const String &, const Float64 &) const { return false; }
bool operator() (const String & l, const String & r) const { return l < r; }
- bool operator() (const String &, const Array &) const { return true; }
- bool operator() (const String &, const Tuple &) const { return true; }
+ bool operator() (const String &, const Array &) const { return true; }
+ bool operator() (const String &, const Tuple &) const { return true; }
bool operator() (const Array &, const Null &) const { return false; }
bool operator() (const Array &, const UInt64 &) const { return false; }
+ bool operator() (const Array &, const UInt128 &) const { return false; }
bool operator() (const Array &, const Int64 &) const { return false; }
bool operator() (const Array &, const Float64 &) const { return false; }
bool operator() (const Array &, const String &) const { return false; }
@@ -294,6 +340,7 @@ public:
bool operator() (const Tuple &, const Null &) const { return false; }
bool operator() (const Tuple &, const UInt64 &) const { return false; }
+ bool operator() (const Tuple &, const UInt128 &) const { return false; }
bool operator() (const Tuple &, const Int64 &) const { return false; }
bool operator() (const Tuple &, const Float64 &) const { return false; }
bool operator() (const Tuple &, const String &) const { return false; }
@@ -318,6 +365,7 @@ public:
bool operator() (Null &) const { throw Exception("Cannot sum Nulls", ErrorCodes::LOGICAL_ERROR); }
bool operator() (String &) const { throw Exception("Cannot sum Strings", ErrorCodes::LOGICAL_ERROR); }
bool operator() (Array &) const { throw Exception("Cannot sum Arrays", ErrorCodes::LOGICAL_ERROR); }
+ bool operator() (UInt128 &) const { throw Exception("Cannot sum UUIDs", ErrorCodes::LOGICAL_ERROR); }
};
}
diff --git a/dbms/src/Common/FileChecker.cpp b/dbms/src/Common/FileChecker.cpp
index e3b1db745ca..bd8e00e38c0 100644
--- a/dbms/src/Common/FileChecker.cpp
+++ b/dbms/src/Common/FileChecker.cpp
@@ -95,13 +95,14 @@ void FileChecker::save() const
/// So complex JSON structure - for compatibility with the old format.
writeCString("{\"yandex\":{", out);
+ auto settings = FormatSettings();
for (auto it = map.begin(); it != map.end(); ++it)
{
if (it != map.begin())
writeString(",", out);
/// `escapeForFileName` is not really needed. But it is left for compatibility with the old code.
- writeJSONString(escapeForFileName(it->first), out);
+ writeJSONString(escapeForFileName(it->first), out, settings);
writeString(":{\"size\":\"", out);
writeIntText(it->second, out);
writeString("\"}", out);
diff --git a/dbms/src/Common/IFactoryWithAliases.h b/dbms/src/Common/IFactoryWithAliases.h
new file mode 100644
index 00000000000..9006a3c7cfd
--- /dev/null
+++ b/dbms/src/Common/IFactoryWithAliases.h
@@ -0,0 +1,125 @@
+#pragma once
+
+#include
+#include
+#include
+
+#include
+
+namespace DB
+{
+
+namespace ErrorCodes
+{
+ extern const int LOGICAL_ERROR;
+}
+
+/** If stored objects may have several names (aliases)
+ * this interface may be helpful
+ * template parameter is available as Creator
+ */
+template
+class IFactoryWithAliases
+{
+protected:
+ using Creator = CreatorFunc;
+
+ String getAliasToOrName(const String & name) const
+ {
+ if (aliases.count(name))
+ return aliases.at(name);
+ else if (String name_lowercase = Poco::toLower(name); case_insensitive_aliases.count(name_lowercase))
+ return case_insensitive_aliases.at(name_lowercase);
+ else
+ return name;
+ }
+
+public:
+ /// For compatibility with SQL, it's possible to specify that certain function name is case insensitive.
+ enum CaseSensitiveness
+ {
+ CaseSensitive,
+ CaseInsensitive
+ };
+
+ /** Register additional name for creator
+ * real_name have to be already registered.
+ */
+ void registerAlias(const String & alias_name, const String & real_name, CaseSensitiveness case_sensitiveness = CaseSensitive)
+ {
+ const auto & creator_map = getCreatorMap();
+ const auto & case_insensitive_creator_map = getCaseInsensitiveCreatorMap();
+ const String factory_name = getFactoryName();
+
+ String real_dict_name;
+ if (creator_map.count(real_name))
+ real_dict_name = real_name;
+ else if (auto real_name_lowercase = Poco::toLower(real_name); case_insensitive_creator_map.count(real_name_lowercase))
+ real_dict_name = real_name_lowercase;
+ else
+ throw Exception(factory_name + ": can't create alias '" + alias_name + "', the real name '" + real_name + "' is not registered",
+ ErrorCodes::LOGICAL_ERROR);
+
+ String alias_name_lowercase = Poco::toLower(alias_name);
+
+ if (creator_map.count(alias_name) || case_insensitive_creator_map.count(alias_name_lowercase))
+ throw Exception(
+ factory_name + ": the alias name '" + alias_name + "' is already registered as real name", ErrorCodes::LOGICAL_ERROR);
+
+ if (case_sensitiveness == CaseInsensitive)
+ if (!case_insensitive_aliases.emplace(alias_name_lowercase, real_dict_name).second)
+ throw Exception(
+ factory_name + ": case insensitive alias name '" + alias_name + "' is not unique", ErrorCodes::LOGICAL_ERROR);
+
+ if (!aliases.emplace(alias_name, real_dict_name).second)
+ throw Exception(factory_name + ": alias name '" + alias_name + "' is not unique", ErrorCodes::LOGICAL_ERROR);
+ }
+
+ std::vector getAllRegisteredNames() const
+ {
+ std::vector result;
+ auto getter = [](const auto & pair) { return pair.first; };
+ std::transform(getCreatorMap().begin(), getCreatorMap().end(), std::back_inserter(result), getter);
+ std::transform(aliases.begin(), aliases.end(), std::back_inserter(result), getter);
+ return result;
+ }
+
+ bool isCaseInsensitive(const String & name) const
+ {
+ String name_lowercase = Poco::toLower(name);
+ return getCaseInsensitiveCreatorMap().count(name_lowercase) || case_insensitive_aliases.count(name_lowercase);
+ }
+
+ const String & aliasTo(const String & name) const
+ {
+ if (auto it = aliases.find(name); it != aliases.end())
+ return it->second;
+ else if (auto it = case_insensitive_aliases.find(Poco::toLower(name)); it != case_insensitive_aliases.end())
+ return it->second;
+
+ throw Exception(getFactoryName() + ": name '" + name + "' is not alias", ErrorCodes::LOGICAL_ERROR);
+ }
+
+ bool isAlias(const String & name) const
+ {
+ return aliases.count(name) || case_insensitive_aliases.count(name);
+ }
+
+ virtual ~IFactoryWithAliases() {}
+
+private:
+ using InnerMap = std::unordered_map; // name -> creator
+ using AliasMap = std::unordered_map; // alias -> original type
+
+ virtual const InnerMap & getCreatorMap() const = 0;
+ virtual const InnerMap & getCaseInsensitiveCreatorMap() const = 0;
+ virtual String getFactoryName() const = 0;
+
+ /// Alias map to data_types from previous two maps
+ AliasMap aliases;
+
+ /// Case insensitive aliases
+ AliasMap case_insensitive_aliases;
+};
+
+}
diff --git a/dbms/src/Core/Block.cpp b/dbms/src/Core/Block.cpp
index 9083c214662..c3e77c11a92 100644
--- a/dbms/src/Core/Block.cpp
+++ b/dbms/src/Core/Block.cpp
@@ -54,7 +54,7 @@ void Block::insert(size_t position, const ColumnWithTypeAndName & elem)
if (name_pos.second >= position)
++name_pos.second;
- index_by_name[elem.name] = position;
+ index_by_name.emplace(elem.name, position);
data.emplace(data.begin() + position, elem);
}
@@ -68,20 +68,20 @@ void Block::insert(size_t position, ColumnWithTypeAndName && elem)
if (name_pos.second >= position)
++name_pos.second;
- index_by_name[elem.name] = position;
+ index_by_name.emplace(elem.name, position);
data.emplace(data.begin() + position, std::move(elem));
}
void Block::insert(const ColumnWithTypeAndName & elem)
{
- index_by_name[elem.name] = data.size();
+ index_by_name.emplace(elem.name, data.size());
data.emplace_back(elem);
}
void Block::insert(ColumnWithTypeAndName && elem)
{
- index_by_name[elem.name] = data.size();
+ index_by_name.emplace(elem.name, data.size());
data.emplace_back(std::move(elem));
}
diff --git a/dbms/src/Core/Defines.h b/dbms/src/Core/Defines.h
index b7036171e6e..331e226103d 100644
--- a/dbms/src/Core/Defines.h
+++ b/dbms/src/Core/Defines.h
@@ -45,6 +45,7 @@
#define DBMS_MIN_REVISION_WITH_TABLES_STATUS 54226
#define DBMS_MIN_REVISION_WITH_TIME_ZONE_PARAMETER_IN_DATETIME_DATA_TYPE 54337
#define DBMS_MIN_REVISION_WITH_SERVER_DISPLAY_NAME 54372
+#define DBMS_MIN_REVISION_WITH_VERSION_PATCH 54401
/// Version of ClickHouse TCP protocol. Set to git tag with latest protocol change.
#define DBMS_TCP_PROTOCOL_VERSION 54226
diff --git a/dbms/src/Core/Names.h b/dbms/src/Core/Names.h
index 5c3384112ae..ff8252084ac 100644
--- a/dbms/src/Core/Names.h
+++ b/dbms/src/Core/Names.h
@@ -12,5 +12,6 @@ namespace DB
using Names = std::vector;
using NameSet = std::unordered_set;
using NameToNameMap = std::unordered_map;
+using NameToNameSetMap = std::unordered_map;
}
diff --git a/dbms/src/DataStreams/CollapsingSortedBlockInputStream.cpp b/dbms/src/DataStreams/CollapsingSortedBlockInputStream.cpp
index 01127b5029b..91e68bea75f 100644
--- a/dbms/src/DataStreams/CollapsingSortedBlockInputStream.cpp
+++ b/dbms/src/DataStreams/CollapsingSortedBlockInputStream.cpp
@@ -40,60 +40,45 @@ void CollapsingSortedBlockInputStream::reportIncorrectData()
}
-void CollapsingSortedBlockInputStream::insertRows(MutableColumns & merged_columns, size_t & merged_rows, bool last_in_stream)
+void CollapsingSortedBlockInputStream::insertRows(MutableColumns & merged_columns, size_t & merged_rows)
{
if (count_positive == 0 && count_negative == 0)
+ {
+ /// No input rows have been read.
return;
+ }
if (count_positive == count_negative && !last_is_positive)
{
- /// If all the rows in the input streams was collapsed, we still want to give at least one block in the result.
- if (last_in_stream && merged_rows == 0 && !blocks_written)
- {
- LOG_INFO(log, "All rows collapsed");
- ++merged_rows;
- for (size_t i = 0; i < num_columns; ++i)
- merged_columns[i]->insertFrom(*(*last_positive.columns)[i], last_positive.row_num);
- ++merged_rows;
- for (size_t i = 0; i < num_columns; ++i)
- merged_columns[i]->insertFrom(*(*last_negative.columns)[i], last_negative.row_num);
-
- if (out_row_sources_buf)
- {
- /// true flag value means "skip row"
- current_row_sources[last_positive_pos].setSkipFlag(false);
- current_row_sources[last_negative_pos].setSkipFlag(false);
- }
- }
+ /// Input rows exactly cancel out.
+ return;
}
- else
+
+ if (count_positive <= count_negative)
{
- if (count_positive <= count_negative)
- {
- ++merged_rows;
- for (size_t i = 0; i < num_columns; ++i)
- merged_columns[i]->insertFrom(*(*first_negative.columns)[i], first_negative.row_num);
+ ++merged_rows;
+ for (size_t i = 0; i < num_columns; ++i)
+ merged_columns[i]->insertFrom(*(*first_negative.columns)[i], first_negative.row_num);
- if (out_row_sources_buf)
- current_row_sources[first_negative_pos].setSkipFlag(false);
- }
+ if (out_row_sources_buf)
+ current_row_sources[first_negative_pos].setSkipFlag(false);
+ }
- if (count_positive >= count_negative)
- {
- ++merged_rows;
- for (size_t i = 0; i < num_columns; ++i)
- merged_columns[i]->insertFrom(*(*last_positive.columns)[i], last_positive.row_num);
+ if (count_positive >= count_negative)
+ {
+ ++merged_rows;
+ for (size_t i = 0; i < num_columns; ++i)
+ merged_columns[i]->insertFrom(*(*last_positive.columns)[i], last_positive.row_num);
- if (out_row_sources_buf)
- current_row_sources[last_positive_pos].setSkipFlag(false);
- }
+ if (out_row_sources_buf)
+ current_row_sources[last_positive_pos].setSkipFlag(false);
+ }
- if (!(count_positive == count_negative || count_positive + 1 == count_negative || count_positive == count_negative + 1))
- {
- if (count_incorrect_data < MAX_ERROR_MESSAGES)
- reportIncorrectData();
- ++count_incorrect_data;
- }
+ if (!(count_positive == count_negative || count_positive + 1 == count_negative || count_positive == count_negative + 1))
+ {
+ if (count_incorrect_data < MAX_ERROR_MESSAGES)
+ reportIncorrectData();
+ ++count_incorrect_data;
}
if (out_row_sources_buf)
@@ -211,7 +196,7 @@ void CollapsingSortedBlockInputStream::merge(MutableColumns & merged_columns, st
}
/// Write data for last primary key.
- insertRows(merged_columns, merged_rows, true);
+ insertRows(merged_columns, merged_rows);
finished = true;
}
diff --git a/dbms/src/DataStreams/CollapsingSortedBlockInputStream.h b/dbms/src/DataStreams/CollapsingSortedBlockInputStream.h
index e8650b4efc5..776b39c76d0 100644
--- a/dbms/src/DataStreams/CollapsingSortedBlockInputStream.h
+++ b/dbms/src/DataStreams/CollapsingSortedBlockInputStream.h
@@ -74,7 +74,7 @@ private:
void merge(MutableColumns & merged_columns, std::priority_queue & queue);
/// Output to result rows for the current primary key.
- void insertRows(MutableColumns & merged_columns, size_t & merged_rows, bool last_in_stream = false);
+ void insertRows(MutableColumns & merged_columns, size_t & merged_rows);
void reportIncorrectData();
};
diff --git a/dbms/src/DataStreams/CreatingSetsBlockInputStream.cpp b/dbms/src/DataStreams/CreatingSetsBlockInputStream.cpp
index 0a58050339a..a72784ffd96 100644
--- a/dbms/src/DataStreams/CreatingSetsBlockInputStream.cpp
+++ b/dbms/src/DataStreams/CreatingSetsBlockInputStream.cpp
@@ -125,6 +125,21 @@ void CreatingSetsBlockInputStream::createOne(SubqueryForSet & subquery)
if (!done_with_join)
{
+ if (subquery.joined_block_actions)
+ subquery.joined_block_actions->execute(block);
+
+ for (const auto & name_with_alias : subquery.joined_block_aliases)
+ {
+ if (block.has(name_with_alias.first))
+ {
+ auto pos = block.getPositionByName(name_with_alias.first);
+ auto column = block.getByPosition(pos);
+ block.erase(pos);
+ column.name = name_with_alias.second;
+ block.insert(std::move(column));
+ }
+ }
+
if (!subquery.join->insertFromBlock(block))
done_with_join = true;
}
diff --git a/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp b/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp
index 3d7f43a258d..70a0dc8cd77 100644
--- a/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp
+++ b/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp
@@ -71,7 +71,7 @@ void PushingToViewsBlockOutputStream::write(const Block & block)
try
{
BlockInputStreamPtr from = std::make_shared(block);
- InterpreterSelectQuery select(view.query, *views_context, {}, QueryProcessingStage::Complete, 0, from);
+ InterpreterSelectQuery select(view.query, *views_context, from);
BlockInputStreamPtr in = std::make_shared(select.execute().in);
/// Squashing is needed here because the materialized view query can generate a lot of blocks
/// even when only one block is inserted into the parent table (e.g. if the query is a GROUP BY
diff --git a/dbms/src/DataStreams/SummingSortedBlockInputStream.cpp b/dbms/src/DataStreams/SummingSortedBlockInputStream.cpp
index a56b2928fc5..18c122ddc1a 100644
--- a/dbms/src/DataStreams/SummingSortedBlockInputStream.cpp
+++ b/dbms/src/DataStreams/SummingSortedBlockInputStream.cpp
@@ -195,7 +195,7 @@ SummingSortedBlockInputStream::SummingSortedBlockInputStream(
}
-void SummingSortedBlockInputStream::insertCurrentRowIfNeeded(MutableColumns & merged_columns, bool force_insertion)
+void SummingSortedBlockInputStream::insertCurrentRowIfNeeded(MutableColumns & merged_columns)
{
for (auto & desc : columns_to_aggregate)
{
@@ -237,9 +237,9 @@ void SummingSortedBlockInputStream::insertCurrentRowIfNeeded(MutableColumns & me
desc.merged_column->insertDefault();
}
- /// If it is "zero" row and it is not the last row of the result block, then
- /// rollback the insertion (at this moment we need rollback only cols from columns_to_aggregate)
- if (!force_insertion && current_row_is_zero)
+ /// If it is "zero" row, then rollback the insertion
+ /// (at this moment we need rollback only cols from columns_to_aggregate)
+ if (current_row_is_zero)
{
for (auto & desc : columns_to_aggregate)
desc.merged_column->popBack(1);
@@ -252,7 +252,6 @@ void SummingSortedBlockInputStream::insertCurrentRowIfNeeded(MutableColumns & me
/// Update per-block and per-group flags
++merged_rows;
- output_is_non_empty = true;
}
@@ -333,7 +332,7 @@ void SummingSortedBlockInputStream::merge(MutableColumns & merged_columns, std::
{
if (!current_key.empty())
/// Write the data for the previous group.
- insertCurrentRowIfNeeded(merged_columns, false);
+ insertCurrentRowIfNeeded(merged_columns);
if (merged_rows >= max_block_size)
{
@@ -393,7 +392,7 @@ void SummingSortedBlockInputStream::merge(MutableColumns & merged_columns, std::
/// We will write the data for the last group, if it is non-zero.
/// If it is zero, and without it the output stream will be empty, we will write it anyway.
- insertCurrentRowIfNeeded(merged_columns, !output_is_non_empty);
+ insertCurrentRowIfNeeded(merged_columns);
finished = true;
}
diff --git a/dbms/src/DataStreams/SummingSortedBlockInputStream.h b/dbms/src/DataStreams/SummingSortedBlockInputStream.h
index 8cbd3c7c0f2..52c38454598 100644
--- a/dbms/src/DataStreams/SummingSortedBlockInputStream.h
+++ b/dbms/src/DataStreams/SummingSortedBlockInputStream.h
@@ -134,7 +134,6 @@ private:
Row current_row;
bool current_row_is_zero = true; /// Are all summed columns zero (or empty)? It is updated incrementally.
- bool output_is_non_empty = false; /// Have we given out at least one row as a result.
size_t merged_rows = 0; /// Number of rows merged into current result block
/** We support two different cursors - with Collation and without.
@@ -143,8 +142,7 @@ private:
void merge(MutableColumns & merged_columns, std::priority_queue & queue);
/// Insert the summed row for the current group into the result and updates some of per-block flags if the row is not "zero".
- /// If force_insertion=true, then the row will be inserted even if it is "zero"
- void insertCurrentRowIfNeeded(MutableColumns & merged_columns, bool force_insertion);
+ void insertCurrentRowIfNeeded(MutableColumns & merged_columns);
/// Returns true if merge result is not empty
bool mergeMap(const MapDescription & map, Row & row, SortCursor & cursor);
diff --git a/dbms/src/DataStreams/VersionedCollapsingSortedBlockInputStream.cpp b/dbms/src/DataStreams/VersionedCollapsingSortedBlockInputStream.cpp
index 071752137c6..863e021b279 100644
--- a/dbms/src/DataStreams/VersionedCollapsingSortedBlockInputStream.cpp
+++ b/dbms/src/DataStreams/VersionedCollapsingSortedBlockInputStream.cpp
@@ -15,11 +15,11 @@ namespace ErrorCodes
VersionedCollapsingSortedBlockInputStream::VersionedCollapsingSortedBlockInputStream(
const BlockInputStreams & inputs_, const SortDescription & description_,
- const String & sign_column_, size_t max_block_size_, bool can_collapse_all_rows_,
+ const String & sign_column_, size_t max_block_size_,
WriteBuffer * out_row_sources_buf_)
: MergingSortedBlockInputStream(inputs_, description_, max_block_size_, 0, out_row_sources_buf_)
, max_rows_in_queue(std::min(std::max(3, max_block_size_), MAX_ROWS_IN_MULTIVERSION_QUEUE) - 2)
- , current_keys(max_rows_in_queue + 1), can_collapse_all_rows(can_collapse_all_rows_)
+ , current_keys(max_rows_in_queue + 1)
{
sign_column_number = header.getPositionByName(sign_column_);
}
@@ -130,10 +130,7 @@ void VersionedCollapsingSortedBlockInputStream::merge(MutableColumns & merged_co
{
update_queue(current);
- /// If all the rows was collapsed, we still want to give at least one block in the result.
- /// If queue is empty then don't collapse two last rows.
- if (sign == sign_in_queue || (!can_collapse_all_rows && blocks_written == 0
- && merged_rows == 0 && queue.empty() && current_keys.size() == 1))
+ if (sign == sign_in_queue)
current_keys.pushBack(next_key);
else
{
diff --git a/dbms/src/DataStreams/VersionedCollapsingSortedBlockInputStream.h b/dbms/src/DataStreams/VersionedCollapsingSortedBlockInputStream.h
index 636ee5e3833..5e84284d2ee 100644
--- a/dbms/src/DataStreams/VersionedCollapsingSortedBlockInputStream.h
+++ b/dbms/src/DataStreams/VersionedCollapsingSortedBlockInputStream.h
@@ -176,7 +176,7 @@ public:
/// max_rows_in_queue should be about max_block_size_ if we won't store a lot of extra blocks (RowRef holds SharedBlockPtr).
VersionedCollapsingSortedBlockInputStream(
const BlockInputStreams & inputs_, const SortDescription & description_,
- const String & sign_column_, size_t max_block_size_, bool can_collapse_all_rows_,
+ const String & sign_column_, size_t max_block_size_,
WriteBuffer * out_row_sources_buf_ = nullptr);
String getName() const override { return "VersionedCollapsingSorted"; }
@@ -203,8 +203,6 @@ private:
/// Sources of rows for VERTICAL merge algorithm. Size equals to (size + number of gaps) in current_keys.
std::queue current_row_sources;
- const bool can_collapse_all_rows;
-
void merge(MutableColumns & merged_columns, std::priority_queue & queue);
/// Output to result row for the current primary key.
diff --git a/dbms/src/DataTypes/DataTypeAggregateFunction.cpp b/dbms/src/DataTypes/DataTypeAggregateFunction.cpp
index 86d96ece5f2..f005f2e2eea 100644
--- a/dbms/src/DataTypes/DataTypeAggregateFunction.cpp
+++ b/dbms/src/DataTypes/DataTypeAggregateFunction.cpp
@@ -212,9 +212,9 @@ void DataTypeAggregateFunction::deserializeTextQuoted(IColumn & column, ReadBuff
}
-void DataTypeAggregateFunction::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings &) const
+void DataTypeAggregateFunction::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) const
{
- writeJSONString(serializeToString(function, column, row_num), ostr);
+ writeJSONString(serializeToString(function, column, row_num), ostr, settings);
}
diff --git a/dbms/src/DataTypes/DataTypeEnum.cpp b/dbms/src/DataTypes/DataTypeEnum.cpp
index e9b87670928..bdc27e3f1be 100644
--- a/dbms/src/DataTypes/DataTypeEnum.cpp
+++ b/dbms/src/DataTypes/DataTypeEnum.cpp
@@ -165,9 +165,9 @@ void DataTypeEnum::deserializeTextQuoted(IColumn & column, ReadBuffer & is
}
template
-void DataTypeEnum::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings &) const
+void DataTypeEnum::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) const
{
- writeJSONString(getNameForValue(static_cast(column).getData()[row_num]), ostr);
+ writeJSONString(getNameForValue(static_cast(column).getData()[row_num]), ostr, settings);
}
template
diff --git a/dbms/src/DataTypes/DataTypeFactory.cpp b/dbms/src/DataTypes/DataTypeFactory.cpp
index bbc1d070db5..b9d25b09544 100644
--- a/dbms/src/DataTypes/DataTypeFactory.cpp
+++ b/dbms/src/DataTypes/DataTypeFactory.cpp
@@ -52,8 +52,10 @@ DataTypePtr DataTypeFactory::get(const ASTPtr & ast) const
throw Exception("Unexpected AST element for data type.", ErrorCodes::UNEXPECTED_AST_STRUCTURE);
}
-DataTypePtr DataTypeFactory::get(const String & family_name, const ASTPtr & parameters) const
+DataTypePtr DataTypeFactory::get(const String & family_name_param, const ASTPtr & parameters) const
{
+ String family_name = getAliasToOrName(family_name_param);
+
if (endsWith(family_name, "WithDictionary"))
{
ASTPtr low_cardinality_params = std::make_shared();
@@ -77,8 +79,9 @@ DataTypePtr DataTypeFactory::get(const String & family_name, const ASTPtr & para
return it->second(parameters);
}
+ String family_name_lowercase = Poco::toLower(family_name);
+
{
- String family_name_lowercase = Poco::toLower(family_name);
DataTypesDictionary::const_iterator it = case_insensitive_data_types.find(family_name_lowercase);
if (case_insensitive_data_types.end() != it)
return it->second(parameters);
@@ -94,11 +97,16 @@ void DataTypeFactory::registerDataType(const String & family_name, Creator creat
throw Exception("DataTypeFactory: the data type family " + family_name + " has been provided "
" a null constructor", ErrorCodes::LOGICAL_ERROR);
+ String family_name_lowercase = Poco::toLower(family_name);
+
+ if (isAlias(family_name) || isAlias(family_name_lowercase))
+ throw Exception("DataTypeFactory: the data type family name '" + family_name + "' is already registered as alias",
+ ErrorCodes::LOGICAL_ERROR);
+
if (!data_types.emplace(family_name, creator).second)
throw Exception("DataTypeFactory: the data type family name '" + family_name + "' is not unique",
ErrorCodes::LOGICAL_ERROR);
- String family_name_lowercase = Poco::toLower(family_name);
if (case_sensitiveness == CaseInsensitive
&& !case_insensitive_data_types.emplace(family_name_lowercase, creator).second)
@@ -106,7 +114,6 @@ void DataTypeFactory::registerDataType(const String & family_name, Creator creat
ErrorCodes::LOGICAL_ERROR);
}
-
void DataTypeFactory::registerSimpleDataType(const String & name, SimpleCreator creator, CaseSensitiveness case_sensitiveness)
{
if (creator == nullptr)
@@ -121,7 +128,6 @@ void DataTypeFactory::registerSimpleDataType(const String & name, SimpleCreator
}, case_sensitiveness);
}
-
void registerDataTypeNumbers(DataTypeFactory & factory);
void registerDataTypeDate(DataTypeFactory & factory);
void registerDataTypeDateTime(DataTypeFactory & factory);
diff --git a/dbms/src/DataTypes/DataTypeFactory.h b/dbms/src/DataTypes/DataTypeFactory.h
index cad176432de..21d22cf932e 100644
--- a/dbms/src/DataTypes/DataTypeFactory.h
+++ b/dbms/src/DataTypes/DataTypeFactory.h
@@ -3,6 +3,7 @@
#include