mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-10-04 23:50:50 +00:00
Merge branch 'master' of https://github.com/yandex/ClickHouse into CLICKHOUSE-2720
This commit is contained in:
commit
8e2f528908
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,7 +9,7 @@
|
||||
# auto generated files
|
||||
*.logrt
|
||||
|
||||
build
|
||||
/build
|
||||
/docs/en_single_page/
|
||||
/docs/ru_single_page/
|
||||
/docs/venv/
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -34,3 +34,6 @@
|
||||
[submodule "contrib/boost"]
|
||||
path = contrib/boost
|
||||
url = https://github.com/ClickHouse-Extras/boost.git
|
||||
[submodule "contrib/llvm"]
|
||||
path = contrib/llvm
|
||||
url = https://github.com/ClickHouse-Extras/llvm
|
||||
|
@ -11,6 +11,7 @@ matrix:
|
||||
#
|
||||
# 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 ]
|
||||
@ -33,6 +34,7 @@ matrix:
|
||||
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-5.0
|
||||
@ -77,6 +79,7 @@ matrix:
|
||||
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
packages: [ pbuilder, fakeroot, debhelper ]
|
||||
|
||||
script:
|
||||
@ -94,6 +97,7 @@ matrix:
|
||||
#
|
||||
# addons:
|
||||
# apt:
|
||||
# update: true
|
||||
# packages: [ pbuilder, fakeroot, debhelper ]
|
||||
#
|
||||
# env:
|
||||
@ -115,6 +119,7 @@ matrix:
|
||||
#
|
||||
# addons:
|
||||
# apt:
|
||||
# update: true
|
||||
# packages: [ pbuilder, fakeroot, debhelper ]
|
||||
#
|
||||
# env:
|
||||
@ -137,7 +142,7 @@ matrix:
|
||||
# - brew link --overwrite gcc || true
|
||||
#
|
||||
# env:
|
||||
# - MATRIX_EVAL="export CC=gcc-7 && export CXX=g++-7"
|
||||
# - MATRIX_EVAL="export CC=gcc-8 && export CXX=g++-8"
|
||||
#
|
||||
# script:
|
||||
# - env CMAKE_FLAGS="-DUSE_INTERNAL_BOOST_LIBRARY=1" utils/travis/normal.sh
|
||||
|
@ -1,3 +1,8 @@
|
||||
# ClickHouse release 1.1.54381, 2018-05-14
|
||||
|
||||
## Bug fixes:
|
||||
* Fixed a nodes leak in ZooKeeper when ClickHouse loses connection to ZooKeeper server.
|
||||
|
||||
# ClickHouse release 1.1.54380, 2018-04-21
|
||||
|
||||
## New features:
|
||||
@ -16,7 +21,7 @@
|
||||
* Fixed an error in ZooKeeper client library which led to watches loses, freezing of distributed DDL queue and slowing replication queue if non-empty `chroot` prefix is used in ZooKeeper configuration.
|
||||
|
||||
## Backward incompatible changes:
|
||||
* Removed support of expressions like `(a, b) IN (SELECT (a, b))` (instead of them you can use their equivalent `(a, b) IN (SELECT a, b)`). In previous releases, these expressions led to undermined data filtering or caused errors.
|
||||
* Removed support of expressions like `(a, b) IN (SELECT (a, b))` (instead of them you can use their equivalent `(a, b) IN (SELECT a, b)`). In previous releases, these expressions led to undetermined data filtering or caused errors.
|
||||
|
||||
# ClickHouse release 1.1.54378, 2018-04-16
|
||||
## New features:
|
||||
|
@ -1,3 +1,8 @@
|
||||
# ClickHouse release 1.1.54381, 2018-05-14
|
||||
|
||||
## Исправление ошибок:
|
||||
* Исправлена ошибка, приводящая к "утеканию" метаданных в ZooKeeper при потере соединения с сервером ZooKeeper.
|
||||
|
||||
# ClickHouse release 1.1.54380, 2018-04-21
|
||||
|
||||
## Новые возможности:
|
||||
|
@ -17,7 +17,6 @@ else ()
|
||||
message (WARNING "You are using an unsupported compiler! Compilation has only been tested with Clang 5+ and GCC 7+.")
|
||||
endif ()
|
||||
|
||||
|
||||
# Write compile_commands.json
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
|
||||
|
||||
@ -247,6 +246,7 @@ include (cmake/find_boost.cmake)
|
||||
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 ()
|
||||
|
142
ci/README.md
Normal file
142
ci/README.md
Normal file
@ -0,0 +1,142 @@
|
||||
## Build and test ClickHouse on various plaforms
|
||||
|
||||
Quick and dirty scripts.
|
||||
|
||||
Usage example:
|
||||
```
|
||||
./run-with-docker.sh ubuntu:bionic jobs/quick-build/run.sh
|
||||
```
|
||||
|
||||
Another example, check build on ARM 64:
|
||||
```
|
||||
./prepare-docker-image-ubuntu.sh
|
||||
./run-with-docker.sh multiarch/ubuntu-core:arm64-bionic jobs/quick-build/run.sh
|
||||
```
|
||||
|
||||
Another example, check build on FreeBSD:
|
||||
```
|
||||
./prepare-vagrant-image-freebsd.sh
|
||||
./run-with-vagrant.sh freebsd jobs/quick-build/run.sh
|
||||
```
|
||||
|
||||
Look at `default_config` and `jobs/quick-build/run.sh`
|
||||
|
||||
Various possible options. We are not going to automate testing all of them.
|
||||
|
||||
#### CPU architectures:
|
||||
- x86_64;
|
||||
- AArch64.
|
||||
|
||||
x86_64 is the main CPU architecture. We also have minimal support for AArch64.
|
||||
|
||||
#### Operating systems:
|
||||
- Linux;
|
||||
- FreeBSD.
|
||||
|
||||
We also target Mac OS X, but it's more difficult to test.
|
||||
Linux is the main. FreeBSD is also supported as production OS.
|
||||
Mac OS is intended only for development and have minimal support: client should work, server should just start.
|
||||
|
||||
#### Linux distributions:
|
||||
For build:
|
||||
- Ubuntu Bionic;
|
||||
- Ubuntu Trusty.
|
||||
|
||||
For run:
|
||||
- Ubuntu Hardy;
|
||||
- CentOS 5
|
||||
|
||||
We should support almost any Linux to run ClickHouse. That's why we test also on old distributions.
|
||||
|
||||
#### How to obtain sources:
|
||||
- use sources from local working copy;
|
||||
- clone sources from github;
|
||||
- download source tarball.
|
||||
|
||||
#### Compilers:
|
||||
- gcc-7;
|
||||
- gcc-8;
|
||||
- clang-6;
|
||||
- clang-svn.
|
||||
|
||||
#### Compiler installation:
|
||||
- from OS packages;
|
||||
- build from sources.
|
||||
|
||||
#### C++ standard library implementation:
|
||||
- libc++;
|
||||
- libstdc++ with C++11 ABI;
|
||||
- libstdc++ with old ABI.
|
||||
|
||||
When building with clang, libc++ is used. When building with gcc, we choose libstdc++ with C++11 ABI.
|
||||
|
||||
#### Linkers:
|
||||
- ldd;
|
||||
- gold;
|
||||
|
||||
When building with clang on x86_64, ldd is used. Otherwise we use gold.
|
||||
|
||||
#### Build types:
|
||||
- RelWithDebInfo;
|
||||
- Debug;
|
||||
- ASan;
|
||||
- TSan.
|
||||
|
||||
#### Build types, extra:
|
||||
- -g0 for quick build;
|
||||
- enable test coverage;
|
||||
- debug tcmalloc.
|
||||
|
||||
#### What to build:
|
||||
- only `clickhouse` target;
|
||||
- all targets;
|
||||
- debian packages;
|
||||
|
||||
We also have intent to build RPM and simple tgz packages.
|
||||
|
||||
#### Where to get third-party libraries:
|
||||
- from contrib directory (submodules);
|
||||
- from OS packages.
|
||||
|
||||
The only production option is to use libraries from contrib directory.
|
||||
Using libraries from OS packages is discouraged, but we also support this option.
|
||||
|
||||
#### Linkage types:
|
||||
- static;
|
||||
- shared;
|
||||
|
||||
Static linking is the only option for production usage.
|
||||
We also have support for shared linking, but it is indended only for developers.
|
||||
|
||||
#### Make tools:
|
||||
- make;
|
||||
- ninja.
|
||||
|
||||
#### Installation options:
|
||||
- run built `clickhouse` binary directly;
|
||||
- install from packages.
|
||||
|
||||
#### How to obtain packages:
|
||||
- build them;
|
||||
- download from repository.
|
||||
|
||||
#### Sanity checks:
|
||||
- check that clickhouse binary has no dependencies on unexpected shared libraries;
|
||||
- check that source code have no style violations.
|
||||
|
||||
#### Tests:
|
||||
- Functional tests;
|
||||
- Integration tests;
|
||||
- Unit tests;
|
||||
- Simple sh/reference tests;
|
||||
- Performance tests (note that they require predictable computing power);
|
||||
- Tests for external dictionaries (should be moved to integration tests);
|
||||
- Jepsen like tests for quorum inserts (not yet available in opensource).
|
||||
|
||||
#### Tests extra:
|
||||
- Run functional tests with Valgrind.
|
||||
|
||||
#### Static analyzers:
|
||||
- CppCheck;
|
||||
- clang-tidy;
|
||||
- Coverity.
|
38
ci/build-clang-from-sources.sh
Executable file
38
ci/build-clang-from-sources.sh
Executable file
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
source default-config
|
||||
|
||||
# TODO Non debian systems
|
||||
./install-os-packages.sh svn
|
||||
./install-os-packages.sh cmake
|
||||
|
||||
mkdir "${WORKSPACE}/llvm"
|
||||
|
||||
svn co "http://llvm.org/svn/llvm-project/llvm/${CLANG_SOURCES_BRANCH}" "${WORKSPACE}/llvm/llvm"
|
||||
svn co "http://llvm.org/svn/llvm-project/cfe/${CLANG_SOURCES_BRANCH}" "${WORKSPACE}/llvm/llvm/tools/clang"
|
||||
svn co "http://llvm.org/svn/llvm-project/lld/${CLANG_SOURCES_BRANCH}" "${WORKSPACE}/llvm/llvm/tools/lld"
|
||||
svn co "http://llvm.org/svn/llvm-project/polly/${CLANG_SOURCES_BRANCH}" "${WORKSPACE}/llvm/llvm/tools/polly"
|
||||
svn co "http://llvm.org/svn/llvm-project/clang-tools-extra/${CLANG_SOURCES_BRANCH}" "${WORKSPACE}/llvm/llvm/tools/clang/tools/extra"
|
||||
svn co "http://llvm.org/svn/llvm-project/compiler-rt/${CLANG_SOURCES_BRANCH}" "${WORKSPACE}/llvm/llvm/projects/compiler-rt"
|
||||
svn co "http://llvm.org/svn/llvm-project/libcxx/${CLANG_SOURCES_BRANCH}" "${WORKSPACE}/llvm/llvm/projects/libcxx"
|
||||
svn co "http://llvm.org/svn/llvm-project/libcxxabi/${CLANG_SOURCES_BRANCH}" "${WORKSPACE}/llvm/llvm/projects/libcxxabi"
|
||||
|
||||
mkdir "${WORKSPACE}/llvm/build"
|
||||
cd "${WORKSPACE}/llvm/build"
|
||||
|
||||
# NOTE You must build LLVM with the same ABI as ClickHouse.
|
||||
# For example, if you compile ClickHouse with libc++, you must add
|
||||
# -D LLVM_ENABLE_LIBCXX=1
|
||||
# to the line below.
|
||||
|
||||
cmake -D CMAKE_BUILD_TYPE:STRING=Release ../llvm
|
||||
|
||||
make -j $THREADS
|
||||
$SUDO make install
|
||||
hash clang
|
||||
|
||||
cd ../../..
|
||||
|
||||
export CC=clang
|
||||
export CXX=clang++
|
8
ci/build-debian-packages.sh
Executable file
8
ci/build-debian-packages.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
source default-config
|
||||
|
||||
[[ -d "${WORKSPACE}/sources" ]] || die "Run get-sources.sh first"
|
||||
|
||||
./sources/release
|
47
ci/build-gcc-from-sources.sh
Executable file
47
ci/build-gcc-from-sources.sh
Executable file
@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
source default-config
|
||||
|
||||
./install-os-packages.sh curl
|
||||
|
||||
if [[ "${GCC_SOURCES_VERSION}" == "latest" ]]; then
|
||||
GCC_SOURCES_VERSION=$(curl -sSL https://ftpmirror.gnu.org/gcc/ | grep -oE 'gcc-[0-9]+(\.[0-9]+)+' | sort -Vr | head -n1)
|
||||
fi
|
||||
|
||||
GCC_VERSION_SHORT=$(echo "$GCC_SOURCES_VERSION" | grep -oE '[0-9]' | head -n1)
|
||||
|
||||
echo "Will download ${GCC_SOURCES_VERSION} (short version: $GCC_VERSION_SHORT)."
|
||||
|
||||
THREADS=$(grep -c ^processor /proc/cpuinfo)
|
||||
|
||||
mkdir "${WORKSPACE}/gcc"
|
||||
pushd "${WORKSPACE}/gcc"
|
||||
|
||||
wget https://ftpmirror.gnu.org/gcc/${GCC_SOURCES_VERSION}/${GCC_SOURCES_VERSION}.tar.xz
|
||||
tar xf ${GCC_SOURCES_VERSION}.tar.xz
|
||||
pushd ${GCC_SOURCES_VERSION}
|
||||
./contrib/download_prerequisites
|
||||
popd
|
||||
mkdir gcc-build
|
||||
pushd gcc-build
|
||||
../${GCC_SOURCES_VERSION}/configure --enable-languages=c,c++ --disable-multilib
|
||||
make -j $THREADS
|
||||
$SUDO make install
|
||||
|
||||
popd
|
||||
popd
|
||||
|
||||
$SUDO ln -sf /usr/local/bin/gcc /usr/local/bin/gcc-${GCC_GCC_SOURCES_VERSION_SHORT}
|
||||
$SUDO ln -sf /usr/local/bin/g++ /usr/local/bin/g++-${GCC_GCC_SOURCES_VERSION_SHORT}
|
||||
$SUDO ln -sf /usr/local/bin/gcc /usr/local/bin/cc
|
||||
$SUDO ln -sf /usr/local/bin/g++ /usr/local/bin/c++
|
||||
|
||||
echo '/usr/local/lib64' | $SUDO tee /etc/ld.so.conf.d/10_local-lib64.conf
|
||||
$SUDO ldconfig
|
||||
|
||||
hash gcc g++
|
||||
gcc --version
|
||||
|
||||
export CC=gcc
|
||||
export CXX=g++
|
22
ci/build-normal.sh
Executable file
22
ci/build-normal.sh
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
source default-config
|
||||
|
||||
[[ -d "${WORKSPACE}/sources" ]] || die "Run get-sources.sh first"
|
||||
|
||||
mkdir -p "${WORKSPACE}/build"
|
||||
pushd "${WORKSPACE}/build"
|
||||
|
||||
if [[ "${ENABLE_EMBEDDED_COMPILER}" == 1 ]]; then
|
||||
[[ "$USE_LLVM_LIBRARIES_FROM_SYSTEM" == 0 ]] && CMAKE_FLAGS="$CMAKE_FLAGS -D USE_INTERNAL_LLVM_LIBRARY=1"
|
||||
[[ "$USE_LLVM_LIBRARIES_FROM_SYSTEM" != 0 ]] && CMAKE_FLAGS="$CMAKE_FLAGS -D USE_INTERNAL_LLVM_LIBRARY=0"
|
||||
fi
|
||||
|
||||
cmake -D CMAKE_BUILD_TYPE=${BUILD_TYPE} -D ENABLE_EMBEDDED_COMPILER=${ENABLE_EMBEDDED_COMPILER} $CMAKE_FLAGS ../sources
|
||||
|
||||
[[ "$BUILD_TARGETS" != 'all' ]] && BUILD_TARGETS_STRING="--target $BUILD_TARGETS"
|
||||
|
||||
cmake --build . $BUILD_TARGETS_STRING -- -j $THREADS
|
||||
|
||||
popd
|
7
ci/check-docker.sh
Executable file
7
ci/check-docker.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
source default-config
|
||||
|
||||
command -v docker > /dev/null || die "You need to install Docker"
|
||||
docker ps > /dev/null || die "You need to have access to Docker: run '$SUDO usermod -aG docker $USER' and relogin"
|
20
ci/check-syntax.sh
Executable file
20
ci/check-syntax.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
source default-config
|
||||
|
||||
./install-os-packages.sh jq
|
||||
|
||||
[[ -d "${WORKSPACE}/sources" ]] || die "Run get-sources.sh first"
|
||||
|
||||
mkdir -p "${WORKSPACE}/build"
|
||||
pushd "${WORKSPACE}/build"
|
||||
|
||||
cmake -D CMAKE_BUILD_TYPE=Debug $CMAKE_FLAGS ../sources
|
||||
|
||||
make -j $THREADS re2_st # Generated headers
|
||||
|
||||
jq --raw-output '.[] | .command' compile_commands.json | grep -v -P -- '-c .+/contrib/' | sed -r -e 's/-o\s+\S+/-fsyntax-only/' > syntax-commands
|
||||
xargs --arg-file=syntax-commands --max-procs=$THREADS --replace /bin/sh -c "{}"
|
||||
|
||||
popd
|
10
ci/create-sources-tarball.sh
Executable file
10
ci/create-sources-tarball.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
source default-config
|
||||
|
||||
if [[ -d "${WORKSPACE}/sources" ]]; then
|
||||
tar -c -z -f "${WORKSPACE}/sources.tar.gz" --directory "${WORKSPACE}/sources" .
|
||||
else
|
||||
die "Run get-sources first"
|
||||
fi
|
65
ci/default-config
Normal file
65
ci/default-config
Normal file
@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
if [[ -z "$INITIALIZED" ]]; then
|
||||
|
||||
INITIALIZED=1
|
||||
|
||||
SCRIPTPATH=$(pwd)
|
||||
WORKSPACE=${SCRIPTPATH}/workspace
|
||||
PROJECT_ROOT=$(cd $SCRIPTPATH/.. && pwd)
|
||||
|
||||
# Almost all scripts take no arguments. Arguments should be in config.
|
||||
|
||||
# get-sources
|
||||
SOURCES_METHOD=local # clone, local, tarball
|
||||
SOURCES_CLONE_URL="https://github.com/yandex/ClickHouse.git"
|
||||
SOURCES_BRANCH="master"
|
||||
SOURCES_COMMIT=HEAD # do checkout of this commit after clone
|
||||
|
||||
# prepare-toolchain
|
||||
COMPILER=gcc # gcc, clang
|
||||
COMPILER_INSTALL_METHOD=packages # packages, sources
|
||||
COMPILER_PACKAGE_VERSION=7 # or 6.0 for clang
|
||||
|
||||
# install-compiler-from-sources
|
||||
CLANG_SOURCES_BRANCH=trunk # or tags/RELEASE_600/final
|
||||
GCC_SOURCES_VERSION=latest # or gcc-7.1.0
|
||||
|
||||
# install-libraries
|
||||
USE_LLVM_LIBRARIES_FROM_SYSTEM=0 # 0 or 1
|
||||
ENABLE_EMBEDDED_COMPILER=1
|
||||
|
||||
# build
|
||||
BUILD_METHOD=normal # normal, debian
|
||||
BUILD_TARGETS=clickhouse # tagtet name, all; only for "normal"
|
||||
BUILD_TYPE=RelWithDebInfo # RelWithDebInfo, Debug, ASan, TSan
|
||||
CMAKE_FLAGS=""
|
||||
|
||||
# prepare-docker-image-ubuntu
|
||||
DOCKER_UBUNTU_VERSION=bionic
|
||||
DOCKER_UBUNTU_ARCH=arm64 # How the architecture is named in a tarball at https://partner-images.canonical.com/core/
|
||||
DOCKER_UBUNTU_QUEMU_ARCH=aarch64 # How the architecture is named in QEMU
|
||||
DOCKER_UBUNTU_TAG_ARCH=arm64 # How the architecture is named in Docker
|
||||
DOCKER_UBUNTU_QEMU_VER=v2.9.1
|
||||
DOCKER_UBUNTU_REPO=multiarch/ubuntu-core
|
||||
|
||||
THREADS=$(grep -c ^processor /proc/cpuinfo || nproc || sysctl -a | grep -F 'hw.ncpu' | grep -oE '[0-9]+')
|
||||
|
||||
# All scripts should return 0 in case of success, 1 in case of permanent error,
|
||||
# 2 in case of temporary error, any other code in case of permanent error.
|
||||
function die {
|
||||
echo ${1:-Error}
|
||||
exit ${2:1}
|
||||
}
|
||||
|
||||
[[ $EUID -ne 0 ]] && SUDO=sudo
|
||||
|
||||
./install-os-packages.sh prepare
|
||||
|
||||
# Configuration parameters may be overriden with CONFIG environment variable pointing to config file.
|
||||
[[ -n "$CONFIG" ]] && source $CONFIG
|
||||
|
||||
mkdir -p $WORKSPACE
|
||||
|
||||
fi
|
21
ci/docker-multiarch/LICENSE
Normal file
21
ci/docker-multiarch/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Multiarch
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
53
ci/docker-multiarch/README.md
Normal file
53
ci/docker-multiarch/README.md
Normal file
@ -0,0 +1,53 @@
|
||||
Source: https://github.com/multiarch/ubuntu-core
|
||||
Commit: 3972a7794b40a965615abd710759d3ed439c9a55
|
||||
|
||||
# :earth_africa: ubuntu-core
|
||||
|
||||
![](https://raw.githubusercontent.com/multiarch/dockerfile/master/logo.jpg)
|
||||
|
||||
Multiarch Ubuntu images for Docker.
|
||||
|
||||
Based on https://github.com/tianon/docker-brew-ubuntu-core/
|
||||
|
||||
* `multiarch/ubuntu-core` on [Docker Hub](https://hub.docker.com/r/multiarch/ubuntu-core/)
|
||||
* [Available tags](https://hub.docker.com/r/multiarch/ubuntu-core/tags/)
|
||||
|
||||
## Usage
|
||||
|
||||
Once you need to configure binfmt-support on your Docker host.
|
||||
This works locally or remotely (i.e using boot2docker or swarm).
|
||||
|
||||
```console
|
||||
# configure binfmt-support on the Docker host (works locally or remotely, i.e: using boot2docker)
|
||||
$ docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
```
|
||||
|
||||
Then you can run an `armhf` image from your `x86_64` Docker host.
|
||||
|
||||
```console
|
||||
$ docker run -it --rm multiarch/ubuntu-core:armhf-wily
|
||||
root@a0818570f614:/# uname -a
|
||||
Linux a0818570f614 4.1.13-boot2docker #1 SMP Fri Nov 20 19:05:50 UTC 2015 armv7l armv7l armv7l GNU/Linux
|
||||
root@a0818570f614:/# exit
|
||||
```
|
||||
|
||||
Or an `x86_64` image from your `x86_64` Docker host, directly, without qemu emulation.
|
||||
|
||||
```console
|
||||
$ docker run -it --rm multiarch/ubuntu-core:amd64-wily
|
||||
root@27fe384370c9:/# uname -a
|
||||
Linux 27fe384370c9 4.1.13-boot2docker #1 SMP Fri Nov 20 19:05:50 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
|
||||
root@27fe384370c9:/#
|
||||
```
|
||||
|
||||
It also works for `arm64`
|
||||
|
||||
```console
|
||||
$ docker run -it --rm multiarch/ubuntu-core:arm64-wily
|
||||
root@723fb9f184fa:/# uname -a
|
||||
Linux 723fb9f184fa 4.1.13-boot2docker #1 SMP Fri Nov 20 19:05:50 UTC 2015 aarch64 aarch64 aarch64 GNU/Linux
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
96
ci/docker-multiarch/update.sh
Executable file
96
ci/docker-multiarch/update.sh
Executable file
@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
# A POSIX variable
|
||||
OPTIND=1 # Reset in case getopts has been used previously in the shell.
|
||||
|
||||
while getopts "a:v:q:u:d:t:" opt; do
|
||||
case "$opt" in
|
||||
a) ARCH=$OPTARG
|
||||
;;
|
||||
v) VERSION=$OPTARG
|
||||
;;
|
||||
q) QEMU_ARCH=$OPTARG
|
||||
;;
|
||||
u) QEMU_VER=$OPTARG
|
||||
;;
|
||||
d) DOCKER_REPO=$OPTARG
|
||||
;;
|
||||
t) TAG_ARCH=$OPTARG
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
thisTarBase="ubuntu-$VERSION-core-cloudimg-$ARCH"
|
||||
thisTar="$thisTarBase-root.tar.gz"
|
||||
baseUrl="https://partner-images.canonical.com/core/$VERSION"
|
||||
|
||||
|
||||
# install qemu-user-static
|
||||
if [ -n "${QEMU_ARCH}" ]; then
|
||||
if [ ! -f x86_64_qemu-${QEMU_ARCH}-static.tar.gz ]; then
|
||||
wget -N https://github.com/multiarch/qemu-user-static/releases/download/${QEMU_VER}/x86_64_qemu-${QEMU_ARCH}-static.tar.gz
|
||||
fi
|
||||
tar -xvf x86_64_qemu-${QEMU_ARCH}-static.tar.gz -C $ROOTFS/usr/bin/
|
||||
fi
|
||||
|
||||
|
||||
# get the image
|
||||
if \
|
||||
wget -q --spider "$baseUrl/current" \
|
||||
&& wget -q --spider "$baseUrl/current/$thisTar" \
|
||||
; then
|
||||
baseUrl+='/current'
|
||||
fi
|
||||
wget -qN "$baseUrl/"{{MD5,SHA{1,256}}SUMS{,.gpg},"$thisTarBase.manifest",'unpacked/build-info.txt'} || true
|
||||
wget -N "$baseUrl/$thisTar"
|
||||
|
||||
# check checksum
|
||||
if [ -f SHA256SUMS ]; then
|
||||
sha256sum="$(sha256sum "$thisTar" | cut -d' ' -f1)"
|
||||
if ! grep -q "$sha256sum" SHA256SUMS; then
|
||||
echo >&2 "error: '$thisTar' has invalid SHA256"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
cat > Dockerfile <<-EOF
|
||||
FROM scratch
|
||||
ADD $thisTar /
|
||||
ENV ARCH=${ARCH} UBUNTU_SUITE=${VERSION} DOCKER_REPO=${DOCKER_REPO}
|
||||
EOF
|
||||
|
||||
# add qemu-user-static binary
|
||||
if [ -n "${QEMU_ARCH}" ]; then
|
||||
cat >> Dockerfile <<EOF
|
||||
|
||||
# Add qemu-user-static binary for amd64 builders
|
||||
ADD x86_64_qemu-${QEMU_ARCH}-static.tar.gz /usr/bin
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >> Dockerfile <<-EOF
|
||||
# a few minor docker-specific tweaks
|
||||
# see https://github.com/docker/docker/blob/master/contrib/mkimage/debootstrap
|
||||
RUN echo '#!/bin/sh' > /usr/sbin/policy-rc.d \\
|
||||
&& echo 'exit 101' >> /usr/sbin/policy-rc.d \\
|
||||
&& chmod +x /usr/sbin/policy-rc.d \\
|
||||
&& dpkg-divert --local --rename --add /sbin/initctl \\
|
||||
&& cp -a /usr/sbin/policy-rc.d /sbin/initctl \\
|
||||
&& sed -i 's/^exit.*/exit 0/' /sbin/initctl \\
|
||||
&& echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \\
|
||||
&& echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean \\
|
||||
&& echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean \\
|
||||
&& echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \\
|
||||
&& echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \\
|
||||
&& echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes
|
||||
|
||||
# enable the universe
|
||||
RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list
|
||||
|
||||
# overwrite this with 'CMD []' in a dependent Dockerfile
|
||||
CMD ["/bin/bash"]
|
||||
EOF
|
||||
|
||||
docker build -t "${DOCKER_REPO}:${TAG_ARCH}-${VERSION}" .
|
||||
docker run --rm "${DOCKER_REPO}:${TAG_ARCH}-${VERSION}" /bin/bash -ec "echo Hello from Ubuntu!"
|
18
ci/get-sources.sh
Executable file
18
ci/get-sources.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
source default-config
|
||||
|
||||
if [[ "$SOURCES_METHOD" == "clone" ]]; then
|
||||
./install-os-packages.sh git
|
||||
SOURCES_DIR="${WORKSPACE}/sources"
|
||||
mkdir -p "${SOURCES_DIR}"
|
||||
git clone --recursive --branch "$SOURCES_BRANCH" "$SOURCES_CLONE_URL" "${SOURCES_DIR}"
|
||||
pushd "${SOURCES_DIR}"
|
||||
git checkout --recurse-submodules "$SOURCES_COMMIT"
|
||||
popd
|
||||
elif [[ "$SOURCES_METHOD" == "local" ]]; then
|
||||
ln -f -s "${PROJECT_ROOT}" "${WORKSPACE}/sources"
|
||||
else
|
||||
die "Unknown SOURCES_METHOD"
|
||||
fi
|
22
ci/install-compiler-from-packages.sh
Executable file
22
ci/install-compiler-from-packages.sh
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
source default-config
|
||||
|
||||
# TODO Install from PPA on older Ubuntu
|
||||
|
||||
./install-os-packages.sh ${COMPILER}-${COMPILER_PACKAGE_VERSION}
|
||||
|
||||
if [[ "$COMPILER" == "gcc" ]]; then
|
||||
if command -v gcc-${COMPILER_PACKAGE_VERSION}; then export CC=gcc-${COMPILER_PACKAGE_VERSION} CXX=g++-${COMPILER_PACKAGE_VERSION};
|
||||
elif command -v gcc${COMPILER_PACKAGE_VERSION}; then export CC=gcc${COMPILER_PACKAGE_VERSION} CXX=g++${COMPILER_PACKAGE_VERSION};
|
||||
elif command -v gcc; then export CC=gcc CXX=g++;
|
||||
fi
|
||||
elif [[ "$COMPILER" == "clang" ]]; then
|
||||
if command -v clang-${COMPILER_PACKAGE_VERSION}; then export CC=clang-${COMPILER_PACKAGE_VERSION} CXX=clang++-${COMPILER_PACKAGE_VERSION};
|
||||
elif command -v clang${COMPILER_PACKAGE_VERSION}; then export CC=clang${COMPILER_PACKAGE_VERSION} CXX=clang++${COMPILER_PACKAGE_VERSION};
|
||||
elif command -v clang; then export CC=clang CXX=clang++;
|
||||
fi
|
||||
else
|
||||
die "Unknown compiler specified"
|
||||
fi
|
12
ci/install-compiler-from-sources.sh
Executable file
12
ci/install-compiler-from-sources.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
source default-config
|
||||
|
||||
if [[ "$COMPILER" == "gcc" ]]; then
|
||||
. build-gcc-from-sources.sh
|
||||
elif [[ "$COMPILER" == "clang" ]]; then
|
||||
. build-clang-from-sources.sh
|
||||
else
|
||||
die "Unknown COMPILER"
|
||||
fi
|
14
ci/install-libraries.sh
Executable file
14
ci/install-libraries.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
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
|
||||
fi
|
120
ci/install-os-packages.sh
Executable file
120
ci/install-os-packages.sh
Executable file
@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
# Dispatches package installation on various OS and distributives
|
||||
|
||||
WHAT=$1
|
||||
|
||||
[[ $EUID -ne 0 ]] && SUDO=sudo
|
||||
|
||||
command -v apt-get && PACKAGE_MANAGER=apt
|
||||
command -v yum && PACKAGE_MANAGER=yum
|
||||
command -v pkg && PACKAGE_MANAGER=pkg
|
||||
|
||||
|
||||
case $PACKAGE_MANAGER in
|
||||
apt)
|
||||
case $WHAT in
|
||||
prepare)
|
||||
$SUDO apt-get update
|
||||
;;
|
||||
svn)
|
||||
$SUDO apt-get install -y subversion
|
||||
;;
|
||||
gcc*)
|
||||
$SUDO apt-get install -y $WHAT ${WHAT/cc/++}
|
||||
;;
|
||||
clang*)
|
||||
$SUDO apt-get install -y $WHAT libc++-dev libc++abi-dev
|
||||
[[ $(uname -m) == "x86_64" ]] && $SUDO apt-get install -y ${WHAT/clang/lld} || true
|
||||
;;
|
||||
git)
|
||||
$SUDO apt-get install -y git
|
||||
;;
|
||||
cmake)
|
||||
$SUDO apt-get install -y cmake3 || $SUDO apt-get install -y cmake
|
||||
;;
|
||||
curl)
|
||||
$SUDO apt-get install -y curl
|
||||
;;
|
||||
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
|
||||
;;
|
||||
qemu-user-static)
|
||||
$SUDO apt-get install -y qemu-user-static
|
||||
;;
|
||||
vagrant-virtualbox)
|
||||
$SUDO apt-get install -y vagrant virtualbox
|
||||
;;
|
||||
*)
|
||||
echo "Unknown package"; exit 1;
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
pkg)
|
||||
case $WHAT in
|
||||
prepare)
|
||||
;;
|
||||
svn)
|
||||
$SUDO pkg install -y subversion
|
||||
;;
|
||||
gcc*)
|
||||
$SUDO pkg install -y ${WHAT/-/}
|
||||
;;
|
||||
clang*)
|
||||
$SUDO pkg install -y clang-devel
|
||||
;;
|
||||
git)
|
||||
$SUDO pkg install -y git
|
||||
;;
|
||||
cmake)
|
||||
$SUDO pkg install -y cmake
|
||||
;;
|
||||
curl)
|
||||
$SUDO pkg install -y curl
|
||||
;;
|
||||
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;
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Unknown distributive"; exit 1;
|
||||
;;
|
||||
esac
|
5
ci/jobs/quick-build/README.md
Normal file
5
ci/jobs/quick-build/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
## Build with debug mode and without many libraries
|
||||
|
||||
This job is intended as first check that build is not broken on wide variety of platforms.
|
||||
|
||||
Results of this build are not intended for production usage.
|
31
ci/jobs/quick-build/run.sh
Executable file
31
ci/jobs/quick-build/run.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
# How to run:
|
||||
# From "ci" directory:
|
||||
# jobs/quick-build/run.sh
|
||||
# or:
|
||||
# ./run-with-docker.sh ubuntu:bionic jobs/quick-build/run.sh
|
||||
|
||||
cd "$(dirname $0)"/../..
|
||||
|
||||
. default-config
|
||||
|
||||
SOURCES_METHOD=local
|
||||
COMPILER=clang
|
||||
COMPILER_INSTALL_METHOD=packages
|
||||
COMPILER_PACKAGE_VERSION=6.0
|
||||
USE_LLVM_LIBRARIES_FROM_SYSTEM=0
|
||||
BUILD_METHOD=normal
|
||||
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"
|
||||
|
||||
[[ $(uname) == "FreeBSD" ]] && COMPILER_PACKAGE_VERSION=devel && export COMPILER_PATH=/usr/local/bin
|
||||
|
||||
. get-sources.sh
|
||||
. prepare-toolchain.sh
|
||||
. install-libraries.sh
|
||||
. build-normal.sh
|
23
ci/prepare-docker-image-ubuntu.sh
Executable file
23
ci/prepare-docker-image-ubuntu.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
source default-config
|
||||
|
||||
./check-docker.sh
|
||||
|
||||
# http://fl47l1n3.net/2015/12/24/binfmt/
|
||||
./install-os-packages.sh qemu-user-static
|
||||
|
||||
pushd docker-multiarch
|
||||
|
||||
$SUDO ./update.sh \
|
||||
-a "$DOCKER_UBUNTU_ARCH" \
|
||||
-v "$DOCKER_UBUNTU_VERSION" \
|
||||
-q "$DOCKER_UBUNTU_QUEMU_ARCH" \
|
||||
-u "$DOCKER_UBUNTU_QEMU_VER" \
|
||||
-d "$DOCKER_UBUNTU_REPO" \
|
||||
-t "$DOCKER_UBUNTU_TAG_ARCH"
|
||||
|
||||
docker run --rm --privileged multiarch/qemu-user-static:register
|
||||
|
||||
popd
|
14
ci/prepare-toolchain.sh
Executable file
14
ci/prepare-toolchain.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
source default-config
|
||||
|
||||
./install-os-packages.sh cmake
|
||||
|
||||
if [[ "$COMPILER_INSTALL_METHOD" == "packages" ]]; then
|
||||
. install-compiler-from-packages.sh
|
||||
elif [[ "$COMPILER_INSTALL_METHOD" == "sources" ]]; then
|
||||
. install-compiler-from-sources.sh
|
||||
else
|
||||
die "Unknown COMPILER_INSTALL_METHOD"
|
||||
fi
|
12
ci/prepare-vagrant-image-freebsd.sh
Executable file
12
ci/prepare-vagrant-image-freebsd.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
source default-config
|
||||
|
||||
./install-os-packages.sh vagrant-virtualbox
|
||||
|
||||
pushd "vagrant-freebsd"
|
||||
vagrant up
|
||||
vagrant ssh-config > vagrant-ssh
|
||||
ssh -F vagrant-ssh default 'uname -a'
|
||||
popd
|
18
ci/run-clickhouse-from-binaries.sh
Executable file
18
ci/run-clickhouse-from-binaries.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
# Usage example:
|
||||
# ./run-with-docker.sh centos:centos6 ./run-clickhouse-from-binaries.sh
|
||||
|
||||
source default-config
|
||||
|
||||
SERVER_BIN="${WORKSPACE}/build/dbms/src/Server/clickhouse"
|
||||
SERVER_CONF="${WORKSPACE}/sources/dbms/src/Server/config.xml"
|
||||
SERVER_DATADIR="${WORKSPACE}/clickhouse"
|
||||
|
||||
[[ -x "$SERVER_BIN" ]] || die "Run build-normal.sh first"
|
||||
[[ -r "$SERVER_CONF" ]] || die "Run get-sources.sh first"
|
||||
|
||||
mkdir -p "${SERVER_DATADIR}"
|
||||
|
||||
$SERVER_BIN server --config-file "$SERVER_CONF" --pid-file="${WORKSPACE}/clickhouse.pid" -- --path "$SERVER_DATADIR"
|
9
ci/run-with-docker.sh
Executable file
9
ci/run-with-docker.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
mkdir -p /var/cache/ccache
|
||||
DOCKER_ENV+=" --mount=type=bind,source=/var/cache/ccache,destination=/ccache -e CCACHE_DIR=/ccache "
|
||||
|
||||
PROJECT_ROOT="$(cd "$(dirname "$0")/.."; pwd -P)"
|
||||
[[ -n "$CONFIG" ]] && DOCKER_ENV="--env=CONFIG"
|
||||
docker run -t --network=host --mount=type=bind,source=${PROJECT_ROOT},destination=/ClickHouse --workdir=/ClickHouse/ci $DOCKER_ENV "$1" "$2"
|
14
ci/run-with-vagrant.sh
Executable file
14
ci/run-with-vagrant.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -x
|
||||
|
||||
[[ -r "vagrant-${1}/vagrant-ssh" ]] || die "Run prepare-vagrant-image-... first."
|
||||
|
||||
pushd vagrant-$1
|
||||
|
||||
shopt -s extglob
|
||||
|
||||
vagrant ssh -c "mkdir -p ClickHouse"
|
||||
scp -q -F vagrant-ssh -r ../../!(*build*) default:~/ClickHouse
|
||||
vagrant ssh -c "cd ClickHouse/ci; $2"
|
||||
|
||||
popd
|
1
ci/vagrant-freebsd/.gitignore
vendored
Normal file
1
ci/vagrant-freebsd/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.vagrant
|
3
ci/vagrant-freebsd/Vagrantfile
vendored
Normal file
3
ci/vagrant-freebsd/Vagrantfile
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.box = "generic/freebsd11"
|
||||
end
|
@ -22,6 +22,10 @@ if (NOT MSVC)
|
||||
set (NOT_MSVC 1)
|
||||
endif ()
|
||||
|
||||
if (NOT APPLE)
|
||||
set (NOT_APPLE 1)
|
||||
endif ()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set (COMPILER_GCC 1)
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
|
@ -1,6 +1,9 @@
|
||||
if (ARCH_FREEBSD)
|
||||
find_library (EXECINFO_LIBRARY execinfo)
|
||||
find_library (ELF_LIBRARY elf)
|
||||
message (STATUS "Using execinfo: ${EXECINFO_LIBRARY}")
|
||||
message (STATUS "Using elf: ${ELF_LIBRARY}")
|
||||
else ()
|
||||
set (EXECINFO_LIBRARY "")
|
||||
set (ELF_LIBRARY "")
|
||||
endif ()
|
||||
|
@ -1,107 +1,57 @@
|
||||
option (ENABLE_EMBEDDED_COMPILER "Set to TRUE to enable support for 'compile' option for query execution" 1)
|
||||
option (USE_INTERNAL_LLVM_LIBRARY "Use bundled or system LLVM library. Default: system library for quicker developer builds." ${APPLE})
|
||||
|
||||
if (ENABLE_EMBEDDED_COMPILER)
|
||||
# Based on source code of YT.
|
||||
# Authors: Ivan Puzyrevskiy, Alexey Lukyanchikov, Ruslan Savchenko.
|
||||
if (USE_INTERNAL_LLVM_LIBRARY AND NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/llvm/llvm/CMakeLists.txt")
|
||||
message (WARNING "submodule contrib/llvm is missing. to fix try run: \n git submodule update --init --recursive")
|
||||
set (USE_INTERNAL_LLVM_LIBRARY 0)
|
||||
endif ()
|
||||
|
||||
# Find LLVM includes and libraries.
|
||||
#
|
||||
# LLVM_VERSION - LLVM version.
|
||||
# LLVM_INCLUDE_DIRS - Directory containing LLVM headers.
|
||||
# LLVM_LIBRARY_DIRS - Directory containing LLVM libraries.
|
||||
# LLVM_CXXFLAGS - C++ compiler flags for files that include LLVM headers.
|
||||
# LLVM_FOUND - True if LLVM was found.
|
||||
if (NOT USE_INTERNAL_LLVM_LIBRARY)
|
||||
set (LLVM_PATHS "/usr/local/lib/llvm")
|
||||
|
||||
# llvm_map_components_to_libraries - Maps LLVM used components to required libraries.
|
||||
# Usage: llvm_map_components_to_libraries(REQUIRED_LLVM_LIBRARIES core jit interpreter native ...)
|
||||
if (LLVM_VERSION)
|
||||
find_package(LLVM ${LLVM_VERSION} CONFIG PATHS ${LLVM_PATHS})
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
find_package(LLVM ${CMAKE_CXX_COMPILER_VERSION} CONFIG PATHS ${LLVM_PATHS})
|
||||
else ()
|
||||
find_package (LLVM 6 CONFIG PATHS ${LLVM_PATHS})
|
||||
if (NOT LLVM_FOUND)
|
||||
find_package (LLVM 5 CONFIG PATHS ${LLVM_PATHS})
|
||||
endif ()
|
||||
if (NOT LLVM_FOUND)
|
||||
find_package (LLVM 7 CONFIG PATHS ${LLVM_PATHS})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(LLVM_VERSION_POSTFIX "${COMPILER_POSTFIX}" CACHE STRING "")
|
||||
if (LLVM_FOUND)
|
||||
# Remove dynamically-linked zlib and libedit from LLVM's dependencies:
|
||||
set_target_properties(LLVMSupport PROPERTIES INTERFACE_LINK_LIBRARIES "-lpthread;LLVMDemangle")
|
||||
set_target_properties(LLVMLineEditor PROPERTIES INTERFACE_LINK_LIBRARIES "LLVMSupport")
|
||||
|
||||
option(LLVM_HAS_RTTI "Enable if LLVM was build with RTTI enabled" ON)
|
||||
set (USE_EMBEDDED_COMPILER 1)
|
||||
endif()
|
||||
else()
|
||||
if (ARCH_FREEBSD)
|
||||
set(LLVM_VERSION_POSTFIX "50" CACHE STRING "")
|
||||
else()
|
||||
set(LLVM_VERSION_POSTFIX "-5.0" CACHE STRING "")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_program(LLVM_CONFIG_EXECUTABLE
|
||||
NAMES llvm-config${LLVM_VERSION_POSTFIX} llvm-config llvm-config-devel
|
||||
PATHS $ENV{LLVM_ROOT}/bin)
|
||||
|
||||
mark_as_advanced(LLVM_CONFIG_EXECUTABLE)
|
||||
|
||||
if(NOT LLVM_CONFIG_EXECUTABLE)
|
||||
message(WARNING "Cannot find LLVM (looking for `llvm-config${LLVM_VERSION_POSTFIX}`, `llvm-config`, `llvm-config-devel`). Please, provide LLVM_ROOT environment variable.")
|
||||
else()
|
||||
set(LLVM_FOUND TRUE)
|
||||
|
||||
execute_process(
|
||||
COMMAND ${LLVM_CONFIG_EXECUTABLE} --version
|
||||
OUTPUT_VARIABLE LLVM_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if(LLVM_VERSION VERSION_LESS "5")
|
||||
message(FATAL_ERROR "LLVM 5+ is required. You have ${LLVM_VERSION} (${LLVM_CONFIG_EXECUTABLE})")
|
||||
endif()
|
||||
|
||||
message(STATUS "LLVM config: ${LLVM_CONFIG_EXECUTABLE}; version: ${LLVM_VERSION}")
|
||||
|
||||
execute_process(
|
||||
COMMAND ${LLVM_CONFIG_EXECUTABLE} --includedir
|
||||
OUTPUT_VARIABLE LLVM_INCLUDE_DIRS
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process(
|
||||
COMMAND ${LLVM_CONFIG_EXECUTABLE} --libdir
|
||||
OUTPUT_VARIABLE LLVM_LIBRARY_DIRS
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process(
|
||||
COMMAND ${LLVM_CONFIG_EXECUTABLE} --cxxflags
|
||||
OUTPUT_VARIABLE LLVM_CXXFLAGS
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process(
|
||||
COMMAND ${LLVM_CONFIG_EXECUTABLE} --targets-built
|
||||
OUTPUT_VARIABLE LLVM_TARGETS_BUILT
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
string(REPLACE " " ";" LLVM_TARGETS_BUILT "${LLVM_TARGETS_BUILT}")
|
||||
|
||||
if (USE_STATIC_LIBRARIES)
|
||||
set (LLVM_CONFIG_ADD "--link-static")
|
||||
endif()
|
||||
|
||||
# Get the link libs we need.
|
||||
function(llvm_map_components_to_libraries RESULT)
|
||||
execute_process(
|
||||
COMMAND ${LLVM_CONFIG_EXECUTABLE} ${LLVM_CONFIG_ADD} --libs ${ARGN}
|
||||
OUTPUT_VARIABLE _tmp
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
string(REPLACE " " ";" _libs_module "${_tmp}")
|
||||
|
||||
#message(STATUS "LLVM Libraries for '${ARGN}': ${_libs_module}")
|
||||
|
||||
execute_process(
|
||||
COMMAND ${LLVM_CONFIG_EXECUTABLE} --system-libs ${ARGN}
|
||||
OUTPUT_VARIABLE _libs_system
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
string(REPLACE "\n" " " _libs_system "${_libs_system}")
|
||||
string(REPLACE " " " " _libs_system "${_libs_system}")
|
||||
string(REPLACE " " ";" _libs_system "${_libs_system}")
|
||||
|
||||
set(${RESULT} ${_libs_module} ${_libs_system} PARENT_SCOPE)
|
||||
endfunction(llvm_map_components_to_libraries)
|
||||
|
||||
message(STATUS "LLVM Include Directory: ${LLVM_INCLUDE_DIRS}")
|
||||
message(STATUS "LLVM Library Directory: ${LLVM_LIBRARY_DIRS}")
|
||||
message(STATUS "LLVM C++ Compiler: ${LLVM_CXXFLAGS}")
|
||||
endif()
|
||||
|
||||
if (LLVM_FOUND AND LLVM_INCLUDE_DIRS AND LLVM_LIBRARY_DIRS)
|
||||
set (LLVM_FOUND 1)
|
||||
set (USE_EMBEDDED_COMPILER 1)
|
||||
set (LLVM_VERSION "7.0.0bundled")
|
||||
set (LLVM_INCLUDE_DIRS
|
||||
${ClickHouse_SOURCE_DIR}/contrib/llvm/llvm/include
|
||||
${ClickHouse_BINARY_DIR}/contrib/llvm/llvm/include
|
||||
${ClickHouse_SOURCE_DIR}/contrib/llvm/clang/include
|
||||
${ClickHouse_BINARY_DIR}/contrib/llvm/clang/include
|
||||
${ClickHouse_BINARY_DIR}/contrib/llvm/llvm/tools/clang/include
|
||||
${ClickHouse_SOURCE_DIR}/contrib/llvm/lld/include
|
||||
${ClickHouse_BINARY_DIR}/contrib/llvm/lld/include
|
||||
${ClickHouse_BINARY_DIR}/contrib/llvm/llvm/tools/lld/include)
|
||||
set (LLVM_LIBRARY_DIRS ${ClickHouse_BINARY_DIR}/contrib/llvm/llvm)
|
||||
endif()
|
||||
|
||||
if (LLVM_FOUND)
|
||||
message(STATUS "LLVM version: ${LLVM_PACKAGE_VERSION}")
|
||||
message(STATUS "LLVM include Directory: ${LLVM_INCLUDE_DIRS}")
|
||||
message(STATUS "LLVM library Directory: ${LLVM_LIBRARY_DIRS}")
|
||||
message(STATUS "LLVM C++ compiler flags: ${LLVM_CXXFLAGS}")
|
||||
endif()
|
||||
endif()
|
||||
|
@ -8,8 +8,21 @@ if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/poco/CMakeLists.txt")
|
||||
set (MISSING_INTERNAL_POCO_LIBRARY 1)
|
||||
endif ()
|
||||
|
||||
set (POCO_COMPONENTS Net XML SQL Data)
|
||||
if (NOT DEFINED ENABLE_POCO_NETSSL OR ENABLE_POCO_NETSSL)
|
||||
list (APPEND POCO_COMPONENTS Crypto NetSSL)
|
||||
endif ()
|
||||
if (NOT DEFINED ENABLE_POCO_MONGODB OR ENABLE_POCO_MONGODB)
|
||||
list (APPEND POCO_COMPONENTS MongoDB)
|
||||
endif ()
|
||||
# TODO: after new poco release with SQL library rename ENABLE_POCO_ODBC -> ENABLE_POCO_SQLODBC
|
||||
if (NOT DEFINED ENABLE_POCO_ODBC OR ENABLE_POCO_ODBC)
|
||||
list (APPEND POCO_COMPONENTS DataODBC)
|
||||
#list (APPEND POCO_COMPONENTS SQLODBC) # future
|
||||
endif ()
|
||||
|
||||
if (NOT USE_INTERNAL_POCO_LIBRARY)
|
||||
find_package (Poco COMPONENTS Net NetSSL XML SQL Data Crypto DataODBC MongoDB)
|
||||
find_package (Poco COMPONENTS ${POCO_COMPONENTS})
|
||||
endif ()
|
||||
|
||||
if (Poco_INCLUDE_DIRS AND Poco_Foundation_LIBRARY)
|
||||
@ -46,13 +59,12 @@ elseif (NOT MISSING_INTERNAL_POCO_LIBRARY)
|
||||
"${ClickHouse_SOURCE_DIR}/contrib/poco/Util/include/"
|
||||
)
|
||||
|
||||
if (NOT DEFINED POCO_ENABLE_MONGODB OR POCO_ENABLE_MONGODB)
|
||||
set (Poco_MongoDB_FOUND 1)
|
||||
if (NOT DEFINED ENABLE_POCO_MONGODB OR ENABLE_POCO_MONGODB)
|
||||
set (USE_POCO_MONGODB 1)
|
||||
set (Poco_MongoDB_LIBRARY PocoMongoDB)
|
||||
set (Poco_MongoDB_INCLUDE_DIRS "${ClickHouse_SOURCE_DIR}/contrib/poco/MongoDB/include/")
|
||||
endif ()
|
||||
|
||||
|
||||
if (EXISTS "${ClickHouse_SOURCE_DIR}/contrib/poco/SQL/ODBC/include/")
|
||||
set (Poco_SQL_FOUND 1)
|
||||
set (Poco_SQL_LIBRARY PocoSQL)
|
||||
@ -60,8 +72,8 @@ elseif (NOT MISSING_INTERNAL_POCO_LIBRARY)
|
||||
"${ClickHouse_SOURCE_DIR}/contrib/poco/SQL/include"
|
||||
"${ClickHouse_SOURCE_DIR}/contrib/poco/Data/include"
|
||||
)
|
||||
if (ODBC_FOUND)
|
||||
set (Poco_SQLODBC_FOUND 1)
|
||||
if ((NOT DEFINED ENABLE_POCO_ODBC OR ENABLE_POCO_ODBC) AND ODBC_FOUND)
|
||||
set (USE_POCO_SQLODBC 1)
|
||||
set (Poco_SQLODBC_INCLUDE_DIRS
|
||||
"${ClickHouse_SOURCE_DIR}/contrib/poco/SQL/ODBC/include/"
|
||||
"${ClickHouse_SOURCE_DIR}/contrib/poco/Data/ODBC/include/"
|
||||
@ -73,8 +85,8 @@ elseif (NOT MISSING_INTERNAL_POCO_LIBRARY)
|
||||
set (Poco_Data_FOUND 1)
|
||||
set (Poco_Data_INCLUDE_DIRS "${ClickHouse_SOURCE_DIR}/contrib/poco/Data/include")
|
||||
set (Poco_Data_LIBRARY PocoData)
|
||||
if (ODBC_FOUND)
|
||||
set (Poco_DataODBC_FOUND 1)
|
||||
if ((NOT DEFINED ENABLE_POCO_ODBC OR ENABLE_POCO_ODBC) AND ODBC_FOUND)
|
||||
set (USE_POCO_DATAODBC 1)
|
||||
set (Poco_DataODBC_INCLUDE_DIRS
|
||||
"${ClickHouse_SOURCE_DIR}/contrib/poco/Data/ODBC/include/"
|
||||
${ODBC_INCLUDE_DIRECTORIES}
|
||||
@ -84,8 +96,8 @@ elseif (NOT MISSING_INTERNAL_POCO_LIBRARY)
|
||||
endif ()
|
||||
|
||||
# TODO! fix internal ssl
|
||||
if (OPENSSL_FOUND AND NOT USE_INTERNAL_SSL_LIBRARY)
|
||||
set (Poco_NetSSL_FOUND 1)
|
||||
if (OPENSSL_FOUND AND NOT USE_INTERNAL_SSL_LIBRARY AND (NOT DEFINED ENABLE_POCO_NETSSL OR ENABLE_POCO_NETSSL))
|
||||
set (USE_POCO_NETSSL 1)
|
||||
set (Poco_NetSSL_LIBRARY PocoNetSSL)
|
||||
set (Poco_Crypto_LIBRARY PocoCrypto)
|
||||
endif ()
|
||||
@ -103,7 +115,7 @@ elseif (NOT MISSING_INTERNAL_POCO_LIBRARY)
|
||||
set (Poco_XML_LIBRARY PocoXML)
|
||||
endif ()
|
||||
|
||||
message(STATUS "Using Poco: ${Poco_INCLUDE_DIRS} : ${Poco_Foundation_LIBRARY},${Poco_Util_LIBRARY},${Poco_Net_LIBRARY},${Poco_NetSSL_LIBRARY},${Poco_XML_LIBRARY},${Poco_Data_LIBRARY},${Poco_DataODBC_LIBRARY},${Poco_MongoDB_LIBRARY}; MongoDB=${Poco_MongoDB_FOUND}, DataODBC=${Poco_DataODBC_FOUND}, NetSSL=${Poco_NetSSL_FOUND}")
|
||||
message(STATUS "Using Poco: ${Poco_INCLUDE_DIRS} : ${Poco_Foundation_LIBRARY},${Poco_Util_LIBRARY},${Poco_Net_LIBRARY},${Poco_NetSSL_LIBRARY},${Poco_XML_LIBRARY},${Poco_Data_LIBRARY},${Poco_DataODBC_LIBRARY},${Poco_MongoDB_LIBRARY}; MongoDB=${USE_POCO_MONGODB}, DataODBC=${Poco_DataODBC_FOUND}, NetSSL=${USE_POCO_NETSSL}")
|
||||
|
||||
# How to make sutable poco:
|
||||
# use branch:
|
||||
|
@ -1,15 +1,10 @@
|
||||
if (APPLE)
|
||||
# lib from libs/libcommon
|
||||
set (RT_LIBRARY "apple_rt")
|
||||
else ()
|
||||
elseif (ARCH_FREEBSD)
|
||||
find_library (RT_LIBRARY rt)
|
||||
else ()
|
||||
set (RT_LIBRARY "")
|
||||
endif ()
|
||||
|
||||
message(STATUS "Using rt: ${RT_LIBRARY}")
|
||||
|
||||
function (target_link_rt_by_force TARGET)
|
||||
if (NOT APPLE)
|
||||
set (FLAGS "-Wl,-no-as-needed -lrt -Wl,-as-needed")
|
||||
set_property (TARGET ${TARGET} APPEND PROPERTY LINK_FLAGS "${FLAGS}")
|
||||
endif ()
|
||||
endfunction ()
|
||||
|
5
cmake/find_termcap.cmake
Normal file
5
cmake/find_termcap.cmake
Normal file
@ -0,0 +1,5 @@
|
||||
find_library (TERMCAP_LIBRARY termcap)
|
||||
if (NOT TERMCAP_LIBRARY)
|
||||
find_library (TERMCAP_LIBRARY tinfo)
|
||||
endif()
|
||||
message (STATUS "Using termcap: ${TERMCAP_LIBRARY}")
|
17
contrib/CMakeLists.txt
vendored
17
contrib/CMakeLists.txt
vendored
@ -21,7 +21,7 @@ if (USE_INTERNAL_RE2_LIBRARY)
|
||||
endif ()
|
||||
|
||||
if (USE_INTERNAL_DOUBLE_CONVERSION_LIBRARY)
|
||||
set (BUILD_TESTING ${ENABLE_TESTS} CACHE INTERNAL "")
|
||||
set (BUILD_TESTING 0 CACHE INTERNAL "")
|
||||
add_subdirectory (double-conversion)
|
||||
endif ()
|
||||
|
||||
@ -113,11 +113,7 @@ if (USE_INTERNAL_RDKAFKA_LIBRARY)
|
||||
endif ()
|
||||
|
||||
if (USE_INTERNAL_CAPNP_LIBRARY)
|
||||
if (APPLE) # tests never end
|
||||
set (BUILD_TESTING 0 CACHE INTERNAL "")
|
||||
else ()
|
||||
set (BUILD_TESTING ${ENABLE_TESTS} CACHE INTERNAL "")
|
||||
endif ()
|
||||
set (BUILD_TESTING 0 CACHE INTERNAL "")
|
||||
set (_save ${CMAKE_CXX_EXTENSIONS})
|
||||
set (CMAKE_CXX_EXTENSIONS)
|
||||
add_subdirectory (capnproto/c++)
|
||||
@ -132,7 +128,7 @@ 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)
|
||||
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!
|
||||
@ -145,8 +141,13 @@ if (USE_INTERNAL_POCO_LIBRARY)
|
||||
set (ENABLE_TESTS ${_save})
|
||||
set (CMAKE_CXX_FLAGS ${save_CMAKE_CXX_FLAGS})
|
||||
set (CMAKE_C_FLAGS ${save_CMAKE_C_FLAGS})
|
||||
if (OPENSSL_FOUND AND TARGET Crypto)
|
||||
|
||||
if (OPENSSL_FOUND AND TARGET Crypto AND (NOT DEFINED ENABLE_POCO_NETSSL OR ENABLE_POCO_NETSSL))
|
||||
# Bug in poco https://github.com/pocoproject/poco/pull/2100 found on macos
|
||||
target_include_directories(Crypto PUBLIC ${OPENSSL_INCLUDE_DIR})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (USE_INTERNAL_LLVM_LIBRARY)
|
||||
add_subdirectory (llvm/llvm)
|
||||
endif ()
|
||||
|
@ -1088,7 +1088,7 @@ class sparsegroup {
|
||||
// This is equivalent to memmove(), but faster on my Intel P4,
|
||||
// at least with gcc4.1 -O2 / glibc 2.3.6.
|
||||
for (size_type i = settings.num_buckets; i > offset; --i)
|
||||
memcpy(group + i, group + i-1, sizeof(*group));
|
||||
memcpy(static_cast<void*>(group + i), group + i-1, sizeof(*group));
|
||||
}
|
||||
|
||||
// Create space at group[offset], without special assumptions about value_type
|
||||
@ -1154,7 +1154,7 @@ class sparsegroup {
|
||||
// at lesat with gcc4.1 -O2 / glibc 2.3.6.
|
||||
assert(settings.num_buckets > 0);
|
||||
for (size_type i = offset; i < settings.num_buckets-1; ++i)
|
||||
memcpy(group + i, group + i+1, sizeof(*group)); // hopefully inlined!
|
||||
memcpy(static_cast<void*>(group + i), group + i+1, sizeof(*group)); // hopefully inlined!
|
||||
group = settings.realloc_or_die(group, settings.num_buckets-1);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
message (STATUS "Building: tcmalloc_minimal_internal")
|
||||
|
||||
add_library (tcmalloc_minimal_internal
|
||||
|
1
contrib/llvm
vendored
Submodule
1
contrib/llvm
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 163def217817c90fb982a6daf384744d8472b92b
|
2
contrib/poco
vendored
2
contrib/poco
vendored
@ -1 +1 @@
|
||||
Subproject commit 2d5a158303adf9d47b980cdcfdb26cee1460704e
|
||||
Subproject commit 3a2d0a833a22ef5e1164a9ada54e3253cb038904
|
@ -99,6 +99,17 @@ else ()
|
||||
install (TARGETS dbms LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT clickhouse)
|
||||
endif ()
|
||||
|
||||
if (USE_EMBEDDED_COMPILER)
|
||||
llvm_map_components_to_libnames(REQUIRED_LLVM_LIBRARIES all)
|
||||
if (TERMCAP_LIBRARY)
|
||||
list(APPEND REQUIRED_LLVM_LIBRARIES ${TERMCAP_LIBRARY})
|
||||
endif ()
|
||||
list(APPEND REQUIRED_LLVM_LIBRARIES ${CMAKE_DL_LIBS})
|
||||
|
||||
target_link_libraries (dbms ${REQUIRED_LLVM_LIBRARIES})
|
||||
target_include_directories (dbms BEFORE PUBLIC ${LLVM_INCLUDE_DIRS})
|
||||
endif ()
|
||||
|
||||
|
||||
if (CMAKE_BUILD_TYPE_UC STREQUAL "RELEASE" OR CMAKE_BUILD_TYPE_UC STREQUAL "RELWITHDEBINFO" OR CMAKE_BUILD_TYPE_UC STREQUAL "MINSIZEREL")
|
||||
# Won't generate debug info for files with heavy template instantiation to achieve faster linking and lower size.
|
||||
@ -136,6 +147,7 @@ target_link_libraries (clickhouse_common_io
|
||||
${Poco_Data_LIBRARY}
|
||||
${ZLIB_LIBRARIES}
|
||||
${EXECINFO_LIBRARY}
|
||||
${ELF_LIBRARY}
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${CMAKE_DL_LIBS}
|
||||
)
|
||||
@ -159,7 +171,7 @@ if (NOT USE_INTERNAL_BOOST_LIBRARY)
|
||||
target_include_directories (clickhouse_common_io BEFORE PUBLIC ${Boost_INCLUDE_DIRS})
|
||||
endif ()
|
||||
|
||||
if (Poco_SQLODBC_FOUND)
|
||||
if (USE_POCO_SQLODBC)
|
||||
target_link_libraries (clickhouse_common_io ${Poco_SQL_LIBRARY})
|
||||
target_link_libraries (dbms ${Poco_SQLODBC_LIBRARY} ${Poco_SQL_LIBRARY})
|
||||
if (NOT USE_INTERNAL_POCO_LIBRARY)
|
||||
@ -173,7 +185,7 @@ if (Poco_Data_FOUND AND NOT USE_INTERNAL_POCO_LIBRARY)
|
||||
target_include_directories (dbms PRIVATE ${Poco_Data_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
if (Poco_DataODBC_FOUND)
|
||||
if (USE_POCO_DATAODBC)
|
||||
target_link_libraries (clickhouse_common_io ${Poco_Data_LIBRARY})
|
||||
target_link_libraries (dbms ${Poco_DataODBC_LIBRARY})
|
||||
if (NOT USE_INTERNAL_POCO_LIBRARY)
|
||||
@ -181,12 +193,11 @@ if (Poco_DataODBC_FOUND)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if (Poco_MongoDB_FOUND)
|
||||
if (USE_POCO_MONGODB)
|
||||
target_link_libraries (dbms ${Poco_MongoDB_LIBRARY})
|
||||
endif()
|
||||
|
||||
if (Poco_NetSSL_FOUND)
|
||||
if (USE_POCO_NETSSL)
|
||||
target_link_libraries (clickhouse_common_io ${Poco_NetSSL_LIBRARY})
|
||||
endif()
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# This strings autochanged from release_lib.sh:
|
||||
set(VERSION_DESCRIBE v1.1.54380-testing)
|
||||
set(VERSION_REVISION 54380)
|
||||
set(VERSION_GITHASH fb4a44a9132ee6c84aa3b0adff9c8d09a8473a15)
|
||||
set(VERSION_DESCRIBE v1.1.54382-testing)
|
||||
set(VERSION_REVISION 54382)
|
||||
set(VERSION_GITHASH fd9938cc463456513eba5dce06a0e75b43997d69)
|
||||
# end of autochange
|
||||
|
||||
set (VERSION_MAJOR 1)
|
||||
|
@ -0,0 +1,34 @@
|
||||
#include <AggregateFunctions/AggregateFunctionFactory.h>
|
||||
#include <AggregateFunctions/AggregateFunctionWindowFunnel.h>
|
||||
#include <AggregateFunctions/Helpers.h>
|
||||
#include <AggregateFunctions/FactoryHelpers.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
AggregateFunctionPtr createAggregateFunctionWindowFunnel(const std::string & name, const DataTypes & arguments, const Array & params)
|
||||
{
|
||||
if (params.size() != 1)
|
||||
throw Exception{"Aggregate function " + name + " requires exactly one parameter.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH};
|
||||
|
||||
if (arguments.size() < 2)
|
||||
throw Exception("Aggregate function " + name + " requires one timestamp argument and at least one event condition.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||
|
||||
if (arguments.size() > AggregateFunctionWindowFunnelData::max_events + 1)
|
||||
throw Exception("Too many event arguments for aggregate function " + name, ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||
|
||||
return std::make_shared<AggregateFunctionWindowFunnel>(arguments, params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void registerAggregateFunctionWindowFunnel(AggregateFunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction("windowFunnel", createAggregateFunctionWindowFunnel, AggregateFunctionFactory::CaseInsensitive);
|
||||
}
|
||||
|
||||
}
|
260
dbms/src/AggregateFunctions/AggregateFunctionWindowFunnel.h
Normal file
260
dbms/src/AggregateFunctions/AggregateFunctionWindowFunnel.h
Normal file
@ -0,0 +1,260 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <DataTypes/DataTypeDateTime.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <IO/ReadHelpers.h>
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include <Common/ArenaAllocator.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <ext/range.h>
|
||||
|
||||
#include <AggregateFunctions/IAggregateFunction.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||
extern const int TOO_MANY_ARGUMENTS_FOR_FUNCTION;
|
||||
}
|
||||
|
||||
struct ComparePairFirst final
|
||||
{
|
||||
template <typename T1, typename T2>
|
||||
bool operator()(const std::pair<T1, T2> & lhs, const std::pair<T1, T2> & rhs) const
|
||||
{
|
||||
return lhs.first < rhs.first;
|
||||
}
|
||||
};
|
||||
|
||||
struct AggregateFunctionWindowFunnelData
|
||||
{
|
||||
static constexpr auto max_events = 32;
|
||||
using TimestampEvent = std::pair<UInt32, UInt8>;
|
||||
|
||||
static constexpr size_t bytes_on_stack = 64;
|
||||
using TimestampEvents = PODArray<TimestampEvent, bytes_on_stack, AllocatorWithStackMemory<Allocator<false>, bytes_on_stack>>;
|
||||
|
||||
using Comparator = ComparePairFirst;
|
||||
|
||||
bool sorted = true;
|
||||
TimestampEvents events_list;
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return events_list.size();
|
||||
}
|
||||
|
||||
void add(UInt32 timestamp, UInt8 event)
|
||||
{
|
||||
// Since most events should have already been sorted by timestamp.
|
||||
if (sorted && events_list.size() > 0 && events_list.back().first > timestamp)
|
||||
sorted = false;
|
||||
events_list.emplace_back(timestamp, event);
|
||||
}
|
||||
|
||||
void merge(const AggregateFunctionWindowFunnelData & other)
|
||||
{
|
||||
const auto size = events_list.size();
|
||||
|
||||
events_list.insert(std::begin(other.events_list), std::end(other.events_list));
|
||||
|
||||
/// either sort whole container or do so partially merging ranges afterwards
|
||||
if (!sorted && !other.sorted)
|
||||
std::sort(std::begin(events_list), std::end(events_list), Comparator{});
|
||||
else
|
||||
{
|
||||
const auto begin = std::begin(events_list);
|
||||
const auto middle = std::next(begin, size);
|
||||
const auto end = std::end(events_list);
|
||||
|
||||
if (!sorted)
|
||||
std::sort(begin, middle, Comparator{});
|
||||
|
||||
if (!other.sorted)
|
||||
std::sort(middle, end, Comparator{});
|
||||
|
||||
std::inplace_merge(begin, middle, end, Comparator{});
|
||||
}
|
||||
|
||||
sorted = true;
|
||||
}
|
||||
|
||||
void sort()
|
||||
{
|
||||
if (!sorted)
|
||||
{
|
||||
std::sort(std::begin(events_list), std::end(events_list), Comparator{});
|
||||
sorted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void serialize(WriteBuffer & buf) const
|
||||
{
|
||||
writeBinary(sorted, buf);
|
||||
writeBinary(events_list.size(), buf);
|
||||
|
||||
for (const auto & events : events_list)
|
||||
{
|
||||
writeBinary(events.first, buf);
|
||||
writeBinary(events.second, buf);
|
||||
}
|
||||
}
|
||||
|
||||
void deserialize(ReadBuffer & buf)
|
||||
{
|
||||
readBinary(sorted, buf);
|
||||
|
||||
size_t size;
|
||||
readBinary(size, buf);
|
||||
|
||||
/// TODO Protection against huge size
|
||||
|
||||
events_list.clear();
|
||||
events_list.resize(size);
|
||||
|
||||
UInt32 timestamp;
|
||||
UInt8 event;
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
readBinary(timestamp, buf);
|
||||
readBinary(event, buf);
|
||||
events_list.emplace_back(timestamp, event);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** Calculates the max event level in a sliding window.
|
||||
* The max size of events is 32, that's enough for funnel analytics
|
||||
*
|
||||
* Usage:
|
||||
* - windowFunnel(window)(timestamp, cond1, cond2, cond3, ....)
|
||||
*/
|
||||
class AggregateFunctionWindowFunnel final
|
||||
: public IAggregateFunctionDataHelper<AggregateFunctionWindowFunnelData, AggregateFunctionWindowFunnel>
|
||||
{
|
||||
private:
|
||||
UInt32 window;
|
||||
UInt8 events_size;
|
||||
|
||||
|
||||
// Loop through the entire events_list, update the event timestamp value
|
||||
// The level path must be 1---2---3---...---check_events_size, find the max event level that statisfied the path in the sliding window.
|
||||
// If found, returns the max event level, else return 0.
|
||||
// The Algorithm complexity is O(n).
|
||||
UInt8 getEventLevel(const AggregateFunctionWindowFunnelData & data) const
|
||||
{
|
||||
if (data.size() == 0)
|
||||
return 0;
|
||||
if (events_size == 1)
|
||||
return 1;
|
||||
|
||||
const_cast<AggregateFunctionWindowFunnelData &>(data).sort();
|
||||
|
||||
// events_timestamp stores the timestamp that latest i-th level event happen withing time window after previous level event.
|
||||
// timestamp defaults to -1, which unsigned timestamp value never meet
|
||||
std::vector<Int32> events_timestamp(events_size, -1);
|
||||
for (const auto & pair : data.events_list)
|
||||
{
|
||||
const auto & timestamp = pair.first;
|
||||
const auto & event_idx = pair.second - 1;
|
||||
if (event_idx == 0)
|
||||
events_timestamp[0] = timestamp;
|
||||
else if (events_timestamp[event_idx - 1] >= 0 && timestamp <= events_timestamp[event_idx - 1] + window)
|
||||
{
|
||||
events_timestamp[event_idx] = events_timestamp[event_idx - 1];
|
||||
if (event_idx + 1 == events_size)
|
||||
return events_size;
|
||||
}
|
||||
}
|
||||
for (size_t event = events_timestamp.size(); event > 0; --event)
|
||||
{
|
||||
if (events_timestamp[event - 1] >= 0)
|
||||
return event;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
String getName() const override
|
||||
{
|
||||
return "windowFunnel";
|
||||
}
|
||||
|
||||
AggregateFunctionWindowFunnel(const DataTypes & arguments, const Array & params)
|
||||
{
|
||||
const auto time_arg = arguments.front().get();
|
||||
if (!typeid_cast<const DataTypeDateTime *>(time_arg) && !typeid_cast<const DataTypeUInt32 *>(time_arg))
|
||||
throw Exception{"Illegal type " + time_arg->getName() + " of first argument of aggregate function " + getName()
|
||||
+ ", must be DateTime or UInt32"};
|
||||
|
||||
for (const auto i : ext::range(1, arguments.size()))
|
||||
{
|
||||
auto cond_arg = arguments[i].get();
|
||||
if (!typeid_cast<const DataTypeUInt8 *>(cond_arg))
|
||||
throw Exception{"Illegal type " + cond_arg->getName() + " of argument " + toString(i + 1) + " of aggregate function "
|
||||
+ getName() + ", must be UInt8",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
|
||||
}
|
||||
|
||||
events_size = arguments.size() - 1;
|
||||
window = params.at(0).safeGet<UInt64>();
|
||||
}
|
||||
|
||||
|
||||
DataTypePtr getReturnType() const override
|
||||
{
|
||||
return std::make_shared<DataTypeUInt8>();
|
||||
}
|
||||
|
||||
void add(AggregateDataPtr place, const IColumn ** columns, const size_t row_num, Arena *) const override
|
||||
{
|
||||
UInt8 event_level = 0;
|
||||
for (const auto i : ext::range(1, events_size + 1))
|
||||
{
|
||||
auto event = static_cast<const ColumnVector<UInt8> *>(columns[i])->getData()[row_num];
|
||||
if (event)
|
||||
{
|
||||
event_level = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (event_level)
|
||||
{
|
||||
this->data(place).add(static_cast<const ColumnVector<UInt32> *>(columns[0])->getData()[row_num], event_level);
|
||||
}
|
||||
}
|
||||
|
||||
void merge(AggregateDataPtr place, ConstAggregateDataPtr rhs, Arena *) const override
|
||||
{
|
||||
this->data(place).merge(this->data(rhs));
|
||||
}
|
||||
|
||||
void serialize(ConstAggregateDataPtr place, WriteBuffer & buf) const override
|
||||
{
|
||||
this->data(place).serialize(buf);
|
||||
}
|
||||
|
||||
void deserialize(AggregateDataPtr place, ReadBuffer & buf, Arena *) const override
|
||||
{
|
||||
this->data(place).deserialize(buf);
|
||||
}
|
||||
|
||||
void insertResultInto(ConstAggregateDataPtr place, IColumn & to) const override
|
||||
{
|
||||
static_cast<ColumnUInt8 &>(to).getData().push_back(getEventLevel(this->data(place)));
|
||||
}
|
||||
|
||||
const char * getHeaderFilePath() const override
|
||||
{
|
||||
return __FILE__;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -14,6 +14,7 @@ void registerAggregateFunctionGroupUniqArray(AggregateFunctionFactory &);
|
||||
void registerAggregateFunctionGroupArrayInsertAt(AggregateFunctionFactory &);
|
||||
void registerAggregateFunctionsQuantile(AggregateFunctionFactory &);
|
||||
void registerAggregateFunctionsSequenceMatch(AggregateFunctionFactory &);
|
||||
void registerAggregateFunctionWindowFunnel(AggregateFunctionFactory &);
|
||||
void registerAggregateFunctionsMinMaxAny(AggregateFunctionFactory &);
|
||||
void registerAggregateFunctionsStatisticsStable(AggregateFunctionFactory &);
|
||||
void registerAggregateFunctionsStatisticsSimple(AggregateFunctionFactory &);
|
||||
@ -45,6 +46,7 @@ void registerAggregateFunctions()
|
||||
registerAggregateFunctionGroupArrayInsertAt(factory);
|
||||
registerAggregateFunctionsQuantile(factory);
|
||||
registerAggregateFunctionsSequenceMatch(factory);
|
||||
registerAggregateFunctionWindowFunnel(factory);
|
||||
registerAggregateFunctionsMinMaxAny(factory);
|
||||
registerAggregateFunctionsStatisticsStable(factory);
|
||||
registerAggregateFunctionsStatisticsSimple(factory);
|
||||
|
@ -17,10 +17,11 @@
|
||||
#include <Common/Exception.h>
|
||||
#include <Common/NetException.h>
|
||||
#include <Common/CurrentMetrics.h>
|
||||
#include <Common/DNSResolver.h>
|
||||
#include <Interpreters/ClientInfo.h>
|
||||
|
||||
#include <Common/config.h>
|
||||
#if Poco_NetSSL_FOUND
|
||||
#if USE_POCO_NETSSL
|
||||
#include <Poco/Net/SecureStreamSocket.h>
|
||||
#endif
|
||||
|
||||
@ -56,7 +57,7 @@ void Connection::connect()
|
||||
|
||||
if (static_cast<bool>(secure))
|
||||
{
|
||||
#if Poco_NetSSL_FOUND
|
||||
#if USE_POCO_NETSSL
|
||||
socket = std::make_unique<Poco::Net::SecureStreamSocket>();
|
||||
#else
|
||||
throw Exception{"tcp_secure protocol is disabled because poco library was built without NetSSL support.", ErrorCodes::SUPPORT_IS_DISABLED};
|
||||
@ -66,7 +67,10 @@ void Connection::connect()
|
||||
{
|
||||
socket = std::make_unique<Poco::Net::StreamSocket>();
|
||||
}
|
||||
socket->connect(resolved_address, timeouts.connection_timeout);
|
||||
|
||||
current_resolved_address = DNSResolver::instance().resolveAddress(host, port);
|
||||
|
||||
socket->connect(current_resolved_address, timeouts.connection_timeout);
|
||||
socket->setReceiveTimeout(timeouts.receive_timeout);
|
||||
socket->setSendTimeout(timeouts.send_timeout);
|
||||
socket->setNoDelay(true);
|
||||
@ -462,6 +466,14 @@ void Connection::sendExternalTablesData(ExternalTablesData & data)
|
||||
LOG_DEBUG(log_wrapper.get(), msg.rdbuf());
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress Connection::getResolvedAddress() const
|
||||
{
|
||||
if (connected)
|
||||
return current_resolved_address;
|
||||
|
||||
return DNSResolver::instance().resolveAddress(host, port);
|
||||
}
|
||||
|
||||
|
||||
bool Connection::poll(size_t timeout_microseconds)
|
||||
{
|
||||
@ -571,6 +583,7 @@ void Connection::initBlockInput()
|
||||
|
||||
void Connection::setDescription()
|
||||
{
|
||||
auto resolved_address = getResolvedAddress();
|
||||
description = host + ":" + toString(resolved_address.port());
|
||||
auto ip_address = resolved_address.host().toString();
|
||||
|
||||
@ -610,7 +623,7 @@ void Connection::fillBlockExtraInfo(BlockExtraInfo & info) const
|
||||
{
|
||||
info.is_valid = true;
|
||||
info.host = host;
|
||||
info.resolved_address = resolved_address.toString();
|
||||
info.resolved_address = getResolvedAddress().toString();
|
||||
info.port = port;
|
||||
info.user = user;
|
||||
}
|
||||
|
@ -53,32 +53,7 @@ class Connection : private boost::noncopyable
|
||||
friend class MultiplexedConnections;
|
||||
|
||||
public:
|
||||
Connection(const String & host_, UInt16 port_, const String & default_database_,
|
||||
const String & user_, const String & password_,
|
||||
const ConnectionTimeouts & timeouts_,
|
||||
const String & client_name_ = "client",
|
||||
Protocol::Compression compression_ = Protocol::Compression::Enable,
|
||||
Protocol::Secure secure_ = Protocol::Secure::Disable,
|
||||
Poco::Timespan sync_request_timeout_ = Poco::Timespan(DBMS_DEFAULT_SYNC_REQUEST_TIMEOUT_SEC, 0))
|
||||
:
|
||||
host(host_), port(port_), default_database(default_database_),
|
||||
user(user_), password(password_), resolved_address(host, port),
|
||||
client_name(client_name_),
|
||||
compression(compression_),
|
||||
secure(secure_),
|
||||
timeouts(timeouts_),
|
||||
sync_request_timeout(sync_request_timeout_),
|
||||
log_wrapper(*this)
|
||||
{
|
||||
/// Don't connect immediately, only on first need.
|
||||
|
||||
if (user.empty())
|
||||
user = "default";
|
||||
|
||||
setDescription();
|
||||
}
|
||||
|
||||
Connection(const String & host_, UInt16 port_, const Poco::Net::SocketAddress & resolved_address_,
|
||||
Connection(const String & host_, UInt16 port_,
|
||||
const String & default_database_,
|
||||
const String & user_, const String & password_,
|
||||
const ConnectionTimeouts & timeouts_,
|
||||
@ -87,10 +62,8 @@ public:
|
||||
Protocol::Secure secure_ = Protocol::Secure::Disable,
|
||||
Poco::Timespan sync_request_timeout_ = Poco::Timespan(DBMS_DEFAULT_SYNC_REQUEST_TIMEOUT_SEC, 0))
|
||||
:
|
||||
host(host_), port(port_),
|
||||
default_database(default_database_),
|
||||
user(user_), password(password_),
|
||||
resolved_address(resolved_address_),
|
||||
host(host_), port(port_), default_database(default_database_),
|
||||
user(user_), password(password_), current_resolved_address(host, port),
|
||||
client_name(client_name_),
|
||||
compression(compression_),
|
||||
secure(secure_),
|
||||
@ -189,6 +162,9 @@ public:
|
||||
size_t outBytesCount() const { return out ? out->count() : 0; }
|
||||
size_t inBytesCount() const { return in ? in->count() : 0; }
|
||||
|
||||
/// Returns initially resolved address
|
||||
Poco::Net::SocketAddress getResolvedAddress() const;
|
||||
|
||||
private:
|
||||
String host;
|
||||
UInt16 port;
|
||||
@ -196,10 +172,9 @@ private:
|
||||
String user;
|
||||
String password;
|
||||
|
||||
/** Address could be resolved beforehand and passed to constructor. Then 'host' and 'port' fields are used just for logging.
|
||||
* Otherwise address is resolved in constructor. Thus, DNS based load balancing is not supported.
|
||||
*/
|
||||
Poco::Net::SocketAddress resolved_address;
|
||||
/// Address is resolved during the first connection (or the following reconnects)
|
||||
/// Use it only for logging purposes
|
||||
Poco::Net::SocketAddress current_resolved_address;
|
||||
|
||||
/// For messages in log and in exceptions.
|
||||
String description;
|
||||
|
@ -54,24 +54,7 @@ public:
|
||||
Protocol::Secure secure_ = Protocol::Secure::Disable)
|
||||
: Base(max_connections_, &Logger::get("ConnectionPool (" + host_ + ":" + toString(port_) + ")")),
|
||||
host(host_), port(port_), default_database(default_database_),
|
||||
user(user_), password(password_), resolved_address(host_, port_),
|
||||
client_name(client_name_), compression(compression_),
|
||||
secure{secure_},
|
||||
timeouts(timeouts)
|
||||
{
|
||||
}
|
||||
|
||||
ConnectionPool(unsigned max_connections_,
|
||||
const String & host_, UInt16 port_, const Poco::Net::SocketAddress & resolved_address_,
|
||||
const String & default_database_,
|
||||
const String & user_, const String & password_,
|
||||
const ConnectionTimeouts & timeouts,
|
||||
const String & client_name_ = "client",
|
||||
Protocol::Compression compression_ = Protocol::Compression::Enable,
|
||||
Protocol::Secure secure_ = Protocol::Secure::Disable)
|
||||
: Base(max_connections_, &Logger::get("ConnectionPool (" + host_ + ":" + toString(port_) + ")")),
|
||||
host(host_), port(port_), default_database(default_database_),
|
||||
user(user_), password(password_), resolved_address(resolved_address_),
|
||||
user(user_), password(password_),
|
||||
client_name(client_name_), compression(compression_),
|
||||
secure{secure_},
|
||||
timeouts(timeouts)
|
||||
@ -102,7 +85,7 @@ protected:
|
||||
ConnectionPtr allocObject() override
|
||||
{
|
||||
return std::make_shared<Connection>(
|
||||
host, port, resolved_address,
|
||||
host, port,
|
||||
default_database, user, password, timeouts,
|
||||
client_name, compression, secure);
|
||||
}
|
||||
@ -114,11 +97,6 @@ private:
|
||||
String user;
|
||||
String password;
|
||||
|
||||
/** The address can be resolved in advance and passed to the constructor. Then `host` and `port` fields are meaningful only for logging.
|
||||
* Otherwise, address is resolved in constructor. That is, DNS balancing is not supported.
|
||||
*/
|
||||
Poco::Net::SocketAddress resolved_address;
|
||||
|
||||
String client_name;
|
||||
Protocol::Compression compression; /// Whether to compress data when interacting with the server.
|
||||
Protocol::Secure secure; /// Whether to encrypt data when interacting with the server.
|
||||
|
@ -193,6 +193,7 @@ public:
|
||||
bool isFixedAndContiguous() const override { return data->isFixedAndContiguous(); }
|
||||
bool valuesHaveFixedSize() const override { return data->valuesHaveFixedSize(); }
|
||||
size_t sizeOfValueIfFixed() const override { return data->sizeOfValueIfFixed(); }
|
||||
StringRef getRawData() const override { return data->getRawData(); }
|
||||
|
||||
/// Not part of the common interface.
|
||||
|
||||
|
@ -129,7 +129,7 @@ public:
|
||||
|
||||
bool isFixedAndContiguous() const override { return true; }
|
||||
size_t sizeOfValueIfFixed() const override { return n; }
|
||||
|
||||
StringRef getRawData() const override { return StringRef(chars.data(), chars.size()); }
|
||||
|
||||
/// Specialized part of interface, not from IColumn.
|
||||
|
||||
|
@ -74,7 +74,7 @@ void ColumnTuple::get(size_t n, Field & res) const
|
||||
{
|
||||
const size_t tuple_size = columns.size();
|
||||
res = Tuple(TupleBackend(tuple_size));
|
||||
TupleBackend & res_arr = DB::get<Tuple &>(res).t;
|
||||
TupleBackend & res_arr = DB::get<Tuple &>(res).toUnderType();
|
||||
for (const auto i : ext::range(0, tuple_size))
|
||||
columns[i]->get(n, res_arr[i]);
|
||||
}
|
||||
@ -91,7 +91,7 @@ void ColumnTuple::insertData(const char *, size_t)
|
||||
|
||||
void ColumnTuple::insert(const Field & x)
|
||||
{
|
||||
const TupleBackend & tuple = DB::get<const Tuple &>(x).t;
|
||||
const TupleBackend & tuple = DB::get<const Tuple &>(x).toUnderType();
|
||||
|
||||
const size_t tuple_size = columns.size();
|
||||
if (tuple.size() != tuple_size)
|
||||
@ -309,8 +309,8 @@ void ColumnTuple::getExtremes(Field & min, Field & max) const
|
||||
min = Tuple(TupleBackend(tuple_size));
|
||||
max = Tuple(TupleBackend(tuple_size));
|
||||
|
||||
auto & min_backend = min.get<Tuple &>().t;
|
||||
auto & max_backend = max.get<Tuple &>().t;
|
||||
auto & min_backend = min.get<Tuple &>().toUnderType();
|
||||
auto & max_backend = max.get<Tuple &>().toUnderType();
|
||||
|
||||
for (const auto i : ext::range(0, tuple_size))
|
||||
columns[i]->getExtremes(min_backend[i], max_backend[i]);
|
||||
|
@ -268,7 +268,7 @@ public:
|
||||
|
||||
bool isFixedAndContiguous() const override { return true; }
|
||||
size_t sizeOfValueIfFixed() const override { return sizeof(T); }
|
||||
|
||||
StringRef getRawData() const override { return StringRef(reinterpret_cast<const char*>(data.data()), data.size()); }
|
||||
|
||||
/** More efficient methods of manipulation - to manipulate with data directly. */
|
||||
Container & getData()
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <Columns/ColumnNullable.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
#include <Core/ColumnWithTypeAndName.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -81,4 +82,18 @@ FilterDescription::FilterDescription(const IColumn & column)
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_COLUMN_FOR_FILTER);
|
||||
}
|
||||
|
||||
|
||||
void checkColumnCanBeUsedAsFilter(const ColumnWithTypeAndName & column_elem)
|
||||
{
|
||||
ConstantFilterDescription const_filter;
|
||||
if (column_elem.column)
|
||||
const_filter = ConstantFilterDescription(*column_elem.column);
|
||||
|
||||
if (!const_filter.always_false && !const_filter.always_true)
|
||||
{
|
||||
auto column = column_elem.column ? column_elem.column : column_elem.type->createColumn();
|
||||
FilterDescription filter(*column);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,4 +29,10 @@ struct FilterDescription
|
||||
explicit FilterDescription(const IColumn & column);
|
||||
};
|
||||
|
||||
|
||||
struct ColumnWithTypeAndName;
|
||||
|
||||
/// Will throw an exception if column_elem is cannot be used as a filter column.
|
||||
void checkColumnCanBeUsedAsFilter(const ColumnWithTypeAndName & column_elem);
|
||||
|
||||
}
|
||||
|
@ -308,6 +308,9 @@ public:
|
||||
/// Values in column are represented as continuous memory segment of fixed size. Implies valuesHaveFixedSize.
|
||||
virtual bool isFixedAndContiguous() const { return false; }
|
||||
|
||||
/// If isFixedAndContiguous, returns the underlying data array, otherwise throws an exception.
|
||||
virtual StringRef getRawData() const { throw Exception("Column " + getName() + " is not a contiguous block of memory", ErrorCodes::NOT_IMPLEMENTED); }
|
||||
|
||||
/// If valuesHaveFixedSize, returns size of value, otherwise throw an exception.
|
||||
virtual size_t sizeOfValueIfFixed() const { throw Exception("Values of column " + getName() + " are not fixed size.", ErrorCodes::CANNOT_GET_SIZE_OF_FIELD); }
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/aio_abi.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/** Small wrappers for asynchronous I/O.
|
||||
|
@ -369,15 +369,17 @@ ConfigProcessor::Files ConfigProcessor::getConfigMergeFiles(const std::string &
|
||||
Files files;
|
||||
|
||||
Poco::Path merge_dir_path(config_path);
|
||||
merge_dir_path.setExtension("d");
|
||||
std::set<std::string> merge_dirs;
|
||||
|
||||
std::vector<std::string> merge_dirs;
|
||||
merge_dirs.push_back(merge_dir_path.toString());
|
||||
if (merge_dir_path.getBaseName() != "conf")
|
||||
{
|
||||
merge_dir_path.setBaseName("conf");
|
||||
merge_dirs.push_back(merge_dir_path.toString());
|
||||
}
|
||||
/// Add path_to_config/config_name.d dir
|
||||
merge_dir_path.setExtension("d");
|
||||
merge_dirs.insert(merge_dir_path.toString());
|
||||
/// 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)
|
||||
{
|
||||
|
@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
#include <Poco/Net/IPAddress.h>
|
||||
#include <Poco/Net/SocketAddress.h>
|
||||
#include <memory>
|
||||
#include <ext/singleton.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/// A singleton implementing global and permanent DNS cache
|
||||
/// It could be updated only manually via drop() method
|
||||
class DNSCache : public ext::singleton<DNSCache>
|
||||
{
|
||||
public:
|
||||
|
||||
DNSCache(const DNSCache &) = delete;
|
||||
|
||||
/// Accepts host names like 'example.com' or '127.0.0.1' or '::1' and resolve its IP
|
||||
Poco::Net::IPAddress resolveHost(const std::string & host);
|
||||
|
||||
/// Accepts host names like 'example.com:port' or '127.0.0.1:port' or '[::1]:port' and resolve its IP and port
|
||||
Poco::Net::SocketAddress resolveHostAndPort(const std::string & host_and_port);
|
||||
|
||||
/// Drops all caches
|
||||
void drop();
|
||||
|
||||
~DNSCache();
|
||||
|
||||
protected:
|
||||
|
||||
DNSCache();
|
||||
|
||||
friend class ext::singleton<DNSCache>;
|
||||
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
};
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#include "DNSCache.h"
|
||||
#include "DNSResolver.h"
|
||||
#include <Common/SimpleCache.h>
|
||||
#include <Common/Exception.h>
|
||||
#include <Core/Types.h>
|
||||
@ -6,6 +6,7 @@
|
||||
#include <Poco/Net/NetException.h>
|
||||
#include <Poco/NumberParser.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <atomic>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -74,34 +75,47 @@ static Poco::Net::IPAddress resolveIPAddressImpl(const std::string & host)
|
||||
}
|
||||
|
||||
|
||||
struct DNSCache::Impl
|
||||
struct DNSResolver::Impl
|
||||
{
|
||||
SimpleCache<decltype(resolveIPAddressImpl), &resolveIPAddressImpl> cache_host;
|
||||
|
||||
/// If disabled, will not make cache lookups, will resolve addresses manually on each call
|
||||
std::atomic<bool> disable_cache{false};
|
||||
};
|
||||
|
||||
|
||||
DNSCache::DNSCache() : impl(std::make_unique<DNSCache::Impl>()) {}
|
||||
DNSResolver::DNSResolver() : impl(std::make_unique<DNSResolver::Impl>()) {}
|
||||
|
||||
Poco::Net::IPAddress DNSCache::resolveHost(const std::string & host)
|
||||
Poco::Net::IPAddress DNSResolver::resolveHost(const std::string & host)
|
||||
{
|
||||
return impl->cache_host(host);
|
||||
return !impl->disable_cache ? impl->cache_host(host) : resolveIPAddressImpl(host);
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress DNSCache::resolveHostAndPort(const std::string & host_and_port)
|
||||
Poco::Net::SocketAddress DNSResolver::resolveAddress(const std::string & host_and_port)
|
||||
{
|
||||
String host;
|
||||
UInt16 port;
|
||||
splitHostAndPort(host_and_port, host, port);
|
||||
|
||||
return Poco::Net::SocketAddress(impl->cache_host(host), port);
|
||||
return !impl->disable_cache ? Poco::Net::SocketAddress(impl->cache_host(host), port) : Poco::Net::SocketAddress(host_and_port);
|
||||
}
|
||||
|
||||
void DNSCache::drop()
|
||||
Poco::Net::SocketAddress DNSResolver::resolveAddress(const std::string & host, UInt16 port)
|
||||
{
|
||||
return !impl->disable_cache ? Poco::Net::SocketAddress(impl->cache_host(host), port) : Poco::Net::SocketAddress(host, port);
|
||||
}
|
||||
|
||||
void DNSResolver::dropCache()
|
||||
{
|
||||
impl->cache_host.drop();
|
||||
}
|
||||
|
||||
DNSCache::~DNSCache() = default;
|
||||
void DNSResolver::setDisableCacheFlag(bool is_disabled)
|
||||
{
|
||||
impl->disable_cache = is_disabled;
|
||||
}
|
||||
|
||||
DNSResolver::~DNSResolver() = default;
|
||||
|
||||
|
||||
}
|
46
dbms/src/Common/DNSResolver.h
Normal file
46
dbms/src/Common/DNSResolver.h
Normal file
@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
#include <Poco/Net/IPAddress.h>
|
||||
#include <Poco/Net/SocketAddress.h>
|
||||
#include <memory>
|
||||
#include <ext/singleton.h>
|
||||
#include <Core/Types.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/// A singleton implementing DNS names resolving with optional permanent DNS cache
|
||||
/// The cache could be updated only manually via drop() method
|
||||
class DNSResolver : public ext::singleton<DNSResolver>
|
||||
{
|
||||
public:
|
||||
|
||||
DNSResolver(const DNSResolver &) = delete;
|
||||
|
||||
/// Accepts host names like 'example.com' or '127.0.0.1' or '::1' and resolve its IP
|
||||
Poco::Net::IPAddress resolveHost(const std::string & host);
|
||||
|
||||
/// Accepts host names like 'example.com:port' or '127.0.0.1:port' or '[::1]:port' and resolve its IP and port
|
||||
Poco::Net::SocketAddress resolveAddress(const std::string & host_and_port);
|
||||
|
||||
Poco::Net::SocketAddress resolveAddress(const std::string & host, UInt16 port);
|
||||
|
||||
/// Disables caching
|
||||
void setDisableCacheFlag(bool is_disabled = true);
|
||||
|
||||
/// Drops all caches
|
||||
void dropCache();
|
||||
|
||||
~DNSResolver();
|
||||
|
||||
protected:
|
||||
|
||||
DNSResolver();
|
||||
|
||||
friend class ext::singleton<DNSResolver>;
|
||||
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
};
|
||||
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <cxxabi.h>
|
||||
|
||||
|
@ -61,7 +61,7 @@ String FieldVisitorDump::operator() (const Array & x) const
|
||||
|
||||
String FieldVisitorDump::operator() (const Tuple & x_def) const
|
||||
{
|
||||
auto & x = x_def.t;
|
||||
auto & x = x_def.toUnderType();
|
||||
WriteBufferFromOwnString wb;
|
||||
|
||||
wb.write("Tuple_(", 7);
|
||||
@ -124,7 +124,7 @@ String FieldVisitorToString::operator() (const Array & x) const
|
||||
|
||||
String FieldVisitorToString::operator() (const Tuple & x_def) const
|
||||
{
|
||||
auto & x = x_def.t;
|
||||
auto & x = x_def.toUnderType();
|
||||
WriteBufferFromOwnString wb;
|
||||
|
||||
writeChar('(', wb);
|
||||
|
@ -408,7 +408,7 @@ protected:
|
||||
|
||||
/// Copy to a new location and zero the old one.
|
||||
x.setHash(hash_value);
|
||||
memcpy(&buf[place_value], &x, sizeof(x));
|
||||
memcpy(static_cast<void*>(&buf[place_value]), &x, sizeof(x));
|
||||
x.setZero();
|
||||
|
||||
/// Then the elements that previously were in collision with this can move to the old place.
|
||||
@ -726,7 +726,7 @@ public:
|
||||
{
|
||||
size_t place_value = findEmptyCell(grower.place(hash_value));
|
||||
|
||||
memcpy(&buf[place_value], cell, sizeof(*cell));
|
||||
memcpy(static_cast<void*>(&buf[place_value]), cell, sizeof(*cell));
|
||||
++m_size;
|
||||
|
||||
if (unlikely(grower.overflow(m_size)))
|
||||
@ -897,7 +897,7 @@ public:
|
||||
this->clearHasZero();
|
||||
m_size = 0;
|
||||
|
||||
memset(buf, 0, grower.bufSize() * sizeof(*buf));
|
||||
memset(static_cast<void*>(buf), 0, grower.bufSize() * sizeof(*buf));
|
||||
}
|
||||
|
||||
/// After executing this function, the table can only be destroyed,
|
||||
|
@ -79,6 +79,8 @@
|
||||
M(CompileAttempt) \
|
||||
M(CompileSuccess) \
|
||||
\
|
||||
M(CompileFunction) \
|
||||
\
|
||||
M(ExternalSortWritePart) \
|
||||
M(ExternalSortMerge) \
|
||||
M(ExternalAggregationWritePart) \
|
||||
@ -138,7 +140,9 @@
|
||||
M(RWLockAcquiredReadLocks) \
|
||||
M(RWLockAcquiredWriteLocks) \
|
||||
M(RWLockReadersWaitMilliseconds) \
|
||||
M(RWLockWritersWaitMilliseconds)
|
||||
M(RWLockWritersWaitMilliseconds) \
|
||||
\
|
||||
M(NetworkErrors)
|
||||
|
||||
namespace ProfileEvents
|
||||
{
|
||||
|
@ -86,8 +86,8 @@ public:
|
||||
if (*needle < 0x80u)
|
||||
{
|
||||
first_needle_symbol_is_ascii = true;
|
||||
l = static_cast<const UInt8>(std::tolower(*needle));
|
||||
u = static_cast<const UInt8>(std::toupper(*needle));
|
||||
l = std::tolower(*needle);
|
||||
u = std::toupper(*needle);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -181,26 +181,31 @@ public:
|
||||
///
|
||||
/// Future should not be destroyed before the result is gotten.
|
||||
|
||||
std::future<ZooKeeperImpl::ZooKeeper::GetResponse> asyncGet(const std::string & path);
|
||||
using FutureGet = std::future<ZooKeeperImpl::ZooKeeper::GetResponse>;
|
||||
FutureGet asyncGet(const std::string & path);
|
||||
|
||||
std::future<ZooKeeperImpl::ZooKeeper::GetResponse> asyncTryGet(const std::string & path);
|
||||
FutureGet asyncTryGet(const std::string & path);
|
||||
|
||||
std::future<ZooKeeperImpl::ZooKeeper::ExistsResponse> asyncExists(const std::string & path);
|
||||
using FutureExists = std::future<ZooKeeperImpl::ZooKeeper::ExistsResponse> ;
|
||||
FutureExists asyncExists(const std::string & path);
|
||||
|
||||
std::future<ZooKeeperImpl::ZooKeeper::ListResponse> asyncGetChildren(const std::string & path);
|
||||
using FutureGetChildren = std::future<ZooKeeperImpl::ZooKeeper::ListResponse>;
|
||||
FutureGetChildren asyncGetChildren(const std::string & path);
|
||||
|
||||
std::future<ZooKeeperImpl::ZooKeeper::RemoveResponse> asyncRemove(const std::string & path, int32_t version = -1);
|
||||
using FutureRemove = std::future<ZooKeeperImpl::ZooKeeper::RemoveResponse>;
|
||||
FutureRemove asyncRemove(const std::string & path, int32_t version = -1);
|
||||
|
||||
/// Doesn't throw in the following cases:
|
||||
/// * The node doesn't exist
|
||||
/// * The versions do not match
|
||||
/// * The node has children
|
||||
std::future<ZooKeeperImpl::ZooKeeper::RemoveResponse> asyncTryRemove(const std::string & path, int32_t version = -1);
|
||||
FutureRemove asyncTryRemove(const std::string & path, int32_t version = -1);
|
||||
|
||||
std::future<ZooKeeperImpl::ZooKeeper::MultiResponse> asyncMulti(const Requests & ops);
|
||||
using FutureMulti = std::future<ZooKeeperImpl::ZooKeeper::MultiResponse>;
|
||||
FutureMulti asyncMulti(const Requests & ops);
|
||||
|
||||
/// Like the previous one but don't throw any exceptions on future.get()
|
||||
std::future<ZooKeeperImpl::ZooKeeper::MultiResponse> tryAsyncMulti(const Requests & ops);
|
||||
FutureMulti tryAsyncMulti(const Requests & ops);
|
||||
|
||||
static std::string error2string(int32_t code);
|
||||
|
||||
|
@ -9,7 +9,8 @@
|
||||
#cmakedefine01 USE_RDKAFKA
|
||||
#cmakedefine01 USE_CAPNP
|
||||
#cmakedefine01 USE_EMBEDDED_COMPILER
|
||||
#cmakedefine01 Poco_SQLODBC_FOUND
|
||||
#cmakedefine01 Poco_DataODBC_FOUND
|
||||
#cmakedefine01 Poco_MongoDB_FOUND
|
||||
#cmakedefine01 Poco_NetSSL_FOUND
|
||||
#cmakedefine01 LLVM_HAS_RTTI
|
||||
#cmakedefine01 USE_POCO_SQLODBC
|
||||
#cmakedefine01 USE_POCO_DATAODBC
|
||||
#cmakedefine01 USE_POCO_MONGODB
|
||||
#cmakedefine01 USE_POCO_NETSSL
|
||||
|
@ -35,10 +35,10 @@ const char * auto_config_build[]
|
||||
"USE_VECTORCLASS", "@USE_VECTORCLASS@",
|
||||
"USE_RDKAFKA", "@USE_RDKAFKA@",
|
||||
"USE_CAPNP", "@USE_CAPNP@",
|
||||
"USE_Poco_SQLODBC", "@Poco_SQLODBC_FOUND@",
|
||||
"USE_Poco_DataODBC", "@Poco_DataODBC_FOUND@",
|
||||
"USE_Poco_MongoDB", "@Poco_MongoDB_FOUND@",
|
||||
"USE_Poco_NetSSL", "@Poco_NetSSL_FOUND@",
|
||||
"USE_POCO_SQLODBC", "@USE_POCO_SQLODBC@",
|
||||
"USE_POCO_DATAODBC", "@USE_POCO_DATAODBC@",
|
||||
"USE_POCO_MONGODB", "@USE_POCO_MONGODB@",
|
||||
"USE_POCO_NETSSL", "@USE_POCO_NETSSL@",
|
||||
|
||||
nullptr, nullptr
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <Common/getNumberOfPhysicalCPUCores.h>
|
||||
#include <thread>
|
||||
#include <fstream>
|
||||
|
||||
#if defined(__x86_64__)
|
||||
|
||||
@ -13,8 +14,26 @@
|
||||
|
||||
unsigned getNumberOfPhysicalCPUCores()
|
||||
{
|
||||
#if defined(__x86_64__)
|
||||
#if defined(__linux__)
|
||||
/// On Linux we try to look at Cgroups limit if it is available.
|
||||
std::ifstream cgroup_read_in("/sys/fs/cgroup/cpu/cpu.cfs_quota_us");
|
||||
if (cgroup_read_in.is_open())
|
||||
{
|
||||
std::string allocated_cpus_share_str{ std::istreambuf_iterator<char>(cgroup_read_in), std::istreambuf_iterator<char>() };
|
||||
int allocated_cpus_share_int = std::stoi(allocated_cpus_share_str);
|
||||
|
||||
cgroup_read_in.close();
|
||||
|
||||
// If a valid value is present
|
||||
if (allocated_cpus_share_int > 0)
|
||||
{
|
||||
unsigned allocated_cpus = (allocated_cpus_share_int + 999) / 1000;
|
||||
return allocated_cpus;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64__)
|
||||
cpu_raw_data_t raw_data;
|
||||
if (0 != cpuid_get_raw_data(&raw_data))
|
||||
throw DB::Exception("Cannot cpuid_get_raw_data: " + std::string(cpuid_error()), DB::ErrorCodes::CPUID_ERROR);
|
||||
|
@ -10,7 +10,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
bool isLocalAddress(const Poco::Net::SocketAddress & address)
|
||||
bool isLocalAddress(const Poco::Net::IPAddress & address)
|
||||
{
|
||||
static auto interfaces = Poco::Net::NetworkInterface::list();
|
||||
|
||||
@ -21,14 +21,14 @@ bool isLocalAddress(const Poco::Net::SocketAddress & address)
|
||||
* Theoretically, this may not be correct - depends on `route` setting
|
||||
* - through which interface we will actually access the specified address.
|
||||
*/
|
||||
return interface.address().length() == address.host().length()
|
||||
&& 0 == memcmp(interface.address().addr(), address.host().addr(), address.host().length());
|
||||
return interface.address().length() == address.length()
|
||||
&& 0 == memcmp(interface.address().addr(), address.addr(), address.length());
|
||||
});
|
||||
}
|
||||
|
||||
bool isLocalAddress(const Poco::Net::SocketAddress & address, UInt16 clickhouse_port)
|
||||
{
|
||||
return clickhouse_port == address.port() && isLocalAddress(address);
|
||||
return clickhouse_port == address.port() && isLocalAddress(address.host());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/Types.h>
|
||||
#include <Poco/Net/IPAddress.h>
|
||||
|
||||
|
||||
namespace Poco
|
||||
{
|
||||
@ -20,10 +22,12 @@ namespace DB
|
||||
* - only the first address is taken for each network interface;
|
||||
* - the routing rules that affect which network interface we go to the specified address are not checked.
|
||||
*/
|
||||
bool isLocalAddress(const Poco::Net::SocketAddress & address, UInt16 clickhouse_port);
|
||||
bool isLocalAddress(const Poco::Net::SocketAddress & address, UInt16 clickhouse_port);
|
||||
|
||||
bool isLocalAddress(const Poco::Net::SocketAddress & address);
|
||||
|
||||
bool isLocalAddress(const Poco::Net::IPAddress & address);
|
||||
|
||||
/// Returns number of different bytes in hostnames, used for load balancing
|
||||
size_t getHostNameDifference(const std::string & local_hostname, const std::string & host);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <Poco/File.h>
|
||||
#include <Common/Exception.h>
|
||||
#include <port/unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
|
@ -143,7 +143,7 @@ namespace DB
|
||||
{
|
||||
inline void readBinary(Tuple & x_def, ReadBuffer & buf)
|
||||
{
|
||||
auto & x = x_def.t;
|
||||
auto & x = x_def.toUnderType();
|
||||
size_t size;
|
||||
DB::readBinary(size, buf);
|
||||
|
||||
@ -214,7 +214,7 @@ namespace DB
|
||||
|
||||
void writeBinary(const Tuple & x_def, WriteBuffer & buf)
|
||||
{
|
||||
auto & x = x_def.t;
|
||||
auto & x = x_def.toUnderType();
|
||||
const size_t size = x.size();
|
||||
DB::writeBinary(size, buf);
|
||||
|
||||
|
@ -361,10 +361,19 @@ private:
|
||||
switch (field.which)
|
||||
{
|
||||
case Types::Null: f(field.template get<Null>()); return;
|
||||
|
||||
// gcc 7.3.0
|
||||
#if !__clang__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
case Types::UInt64: f(field.template get<UInt64>()); return;
|
||||
case Types::UInt128: f(field.template get<UInt128>()); return;
|
||||
case Types::Int64: f(field.template get<Int64>()); return;
|
||||
case Types::Float64: f(field.template get<Float64>()); return;
|
||||
#if !__clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
case Types::String: f(field.template get<String>()); return;
|
||||
case Types::Array: f(field.template get<Array>()); return;
|
||||
case Types::Tuple: f(field.template get<Tuple>()); return;
|
||||
|
@ -150,7 +150,7 @@ private:
|
||||
--ptr->refcount;
|
||||
if (!ptr->refcount)
|
||||
{
|
||||
if (std::uncaught_exception())
|
||||
if (std::uncaught_exceptions())
|
||||
delete ptr;
|
||||
else
|
||||
ptr->output_blocks->push_back(ptr);
|
||||
|
@ -108,6 +108,7 @@ Block MergeSortingBlockInputStream::readImpl()
|
||||
*/
|
||||
if (max_bytes_before_external_sort && sum_bytes_in_blocks > max_bytes_before_external_sort)
|
||||
{
|
||||
Poco::File(tmp_path).createDirectories();
|
||||
temporary_files.emplace_back(new Poco::TemporaryFile(tmp_path));
|
||||
const std::string & path = temporary_files.back()->path();
|
||||
WriteBufferFromFile file_buf(path);
|
||||
|
@ -263,7 +263,7 @@ Block SummingSortedBlockInputStream::readImpl()
|
||||
size_t tuple_size = desc.column_numbers.size();
|
||||
MutableColumns tuple_columns(tuple_size);
|
||||
for (size_t i = 0; i < tuple_size; ++i)
|
||||
tuple_columns[i] = header.safeGetByPosition(desc.column_numbers[i]).column->assumeMutable();
|
||||
tuple_columns[i] = header.safeGetByPosition(desc.column_numbers[i]).column->cloneEmpty();
|
||||
|
||||
desc.merged_column = ColumnTuple::create(std::move(tuple_columns));
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ static inline const IColumn & extractElementColumn(const IColumn & column, size_
|
||||
|
||||
void DataTypeTuple::serializeBinary(const Field & field, WriteBuffer & ostr) const
|
||||
{
|
||||
const auto & tuple = get<const Tuple &>(field).t;
|
||||
const auto & tuple = get<const Tuple &>(field).toUnderType();
|
||||
for (const auto & idx_elem : ext::enumerate(elems))
|
||||
idx_elem.second->serializeBinary(tuple[idx_elem.first], ostr);
|
||||
}
|
||||
@ -107,7 +107,7 @@ void DataTypeTuple::deserializeBinary(Field & field, ReadBuffer & istr) const
|
||||
{
|
||||
const size_t size = elems.size();
|
||||
field = Tuple(TupleBackend(size));
|
||||
TupleBackend & tuple = get<Tuple &>(field).t;
|
||||
TupleBackend & tuple = get<Tuple &>(field).toUnderType();
|
||||
for (const auto i : ext::range(0, size))
|
||||
elems[i]->deserializeBinary(tuple[i], istr);
|
||||
}
|
||||
|
127
dbms/src/DataTypes/Native.h
Normal file
127
dbms/src/DataTypes/Native.h
Normal file
@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
|
||||
#include <Common/config.h>
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <DataTypes/DataTypeDate.h>
|
||||
#include <DataTypes/DataTypeDateTime.h>
|
||||
#include <DataTypes/DataTypeFixedString.h>
|
||||
#include <DataTypes/DataTypeInterval.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <DataTypes/DataTypeUUID.h>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
template <typename... Ts>
|
||||
static inline bool typeIsEither(const IDataType & type)
|
||||
{
|
||||
return (typeid_cast<const Ts *>(&type) || ...);
|
||||
}
|
||||
|
||||
static inline bool typeIsSigned(const IDataType & type)
|
||||
{
|
||||
return typeIsEither<
|
||||
DataTypeInt8, DataTypeInt16, DataTypeInt32, DataTypeInt64,
|
||||
DataTypeFloat32, DataTypeFloat64,
|
||||
DataTypeDate, DataTypeDateTime, DataTypeInterval
|
||||
>(type);
|
||||
}
|
||||
|
||||
static inline llvm::Type * toNativeType(llvm::IRBuilderBase & builder, const IDataType & type)
|
||||
{
|
||||
if (auto * nullable = typeid_cast<const DataTypeNullable *>(&type))
|
||||
{
|
||||
auto * wrapped = toNativeType(builder, *nullable->getNestedType());
|
||||
return wrapped ? llvm::StructType::get(wrapped, /* is null = */ builder.getInt1Ty()) : nullptr;
|
||||
}
|
||||
/// LLVM doesn't have unsigned types, it has unsigned instructions.
|
||||
if (typeIsEither<DataTypeInt8, DataTypeUInt8>(type))
|
||||
return builder.getInt8Ty();
|
||||
if (typeIsEither<DataTypeInt16, DataTypeUInt16, DataTypeDate>(type))
|
||||
return builder.getInt16Ty();
|
||||
if (typeIsEither<DataTypeInt32, DataTypeUInt32, DataTypeDateTime>(type))
|
||||
return builder.getInt32Ty();
|
||||
if (typeIsEither<DataTypeInt64, DataTypeUInt64, DataTypeInterval>(type))
|
||||
return builder.getInt64Ty();
|
||||
if (typeIsEither<DataTypeUUID>(type))
|
||||
return builder.getInt128Ty();
|
||||
if (typeIsEither<DataTypeFloat32>(type))
|
||||
return builder.getFloatTy();
|
||||
if (typeIsEither<DataTypeFloat64>(type))
|
||||
return builder.getDoubleTy();
|
||||
if (auto * fixed_string = typeid_cast<const DataTypeFixedString *>(&type))
|
||||
return llvm::VectorType::get(builder.getInt8Ty(), fixed_string->getN());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static inline llvm::Type * toNativeType(llvm::IRBuilderBase & builder, const DataTypePtr & type)
|
||||
{
|
||||
return toNativeType(builder, *type);
|
||||
}
|
||||
|
||||
static inline llvm::Value * nativeBoolCast(llvm::IRBuilder<> & b, const DataTypePtr & from, llvm::Value * value)
|
||||
{
|
||||
if (from->isNullable())
|
||||
{
|
||||
auto * inner = nativeBoolCast(b, removeNullable(from), b.CreateExtractValue(value, {0}));
|
||||
return b.CreateAnd(b.CreateNot(b.CreateExtractValue(value, {1})), inner);
|
||||
}
|
||||
auto * zero = llvm::Constant::getNullValue(value->getType());
|
||||
if (value->getType()->isIntegerTy())
|
||||
return b.CreateICmpNE(value, zero);
|
||||
if (value->getType()->isFloatingPointTy())
|
||||
return b.CreateFCmpONE(value, zero); /// QNaN is false
|
||||
throw Exception("Cannot cast non-number " + from->getName() + " to bool", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
static inline llvm::Value * nativeCast(llvm::IRBuilder<> & b, const DataTypePtr & from, llvm::Value * value, llvm::Type * to)
|
||||
{
|
||||
auto * n_from = value->getType();
|
||||
if (n_from == to)
|
||||
return value;
|
||||
if (n_from->isIntegerTy() && to->isFloatingPointTy())
|
||||
return typeIsSigned(*from) ? b.CreateSIToFP(value, to) : b.CreateUIToFP(value, to);
|
||||
if (n_from->isFloatingPointTy() && to->isIntegerTy())
|
||||
return typeIsSigned(*from) ? b.CreateFPToSI(value, to) : b.CreateFPToUI(value, to);
|
||||
if (n_from->isIntegerTy() && to->isIntegerTy())
|
||||
return b.CreateIntCast(value, to, typeIsSigned(*from));
|
||||
if (n_from->isFloatingPointTy() && to->isFloatingPointTy())
|
||||
return b.CreateFPCast(value, to);
|
||||
throw Exception("Cannot cast " + from->getName() + " to requested type", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
static inline llvm::Value * nativeCast(llvm::IRBuilder<> & b, const DataTypePtr & from, llvm::Value * value, const DataTypePtr & to)
|
||||
{
|
||||
auto * n_to = toNativeType(b, to);
|
||||
if (value->getType() == n_to)
|
||||
return value;
|
||||
if (from->isNullable() && to->isNullable())
|
||||
{
|
||||
auto * inner = nativeCast(b, removeNullable(from), b.CreateExtractValue(value, {0}), to);
|
||||
return b.CreateInsertValue(inner, b.CreateExtractValue(value, {1}), {1});
|
||||
}
|
||||
if (from->isNullable())
|
||||
return nativeCast(b, removeNullable(from), b.CreateExtractValue(value, {0}), to);
|
||||
if (to->isNullable())
|
||||
{
|
||||
auto * inner = nativeCast(b, from, value, removeNullable(to));
|
||||
return b.CreateInsertValue(llvm::Constant::getNullValue(n_to), inner, {0});
|
||||
}
|
||||
return nativeCast(b, from, value, n_to);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -16,10 +16,10 @@
|
||||
#include <mutex>
|
||||
|
||||
#include <Common/config.h>
|
||||
#if Poco_MongoDB_FOUND
|
||||
#if USE_POCO_MONGODB
|
||||
#include <Dictionaries/MongoDBDictionarySource.h>
|
||||
#endif
|
||||
#if Poco_SQLODBC_FOUND || Poco_DataODBC_FOUND
|
||||
#if USE_POCO_SQLODBC || USE_POCO_DATAODBC
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#include <Poco/Data/ODBC/Connector.h>
|
||||
@ -88,7 +88,7 @@ Block createSampleBlock(const DictionaryStructure & dict_struct)
|
||||
DictionarySourceFactory::DictionarySourceFactory()
|
||||
: log(&Poco::Logger::get("DictionarySourceFactory"))
|
||||
{
|
||||
#if Poco_SQLODBC_FOUND || Poco_DataODBC_FOUND
|
||||
#if USE_POCO_SQLODBC || USE_POCO_DATAODBC
|
||||
Poco::Data::ODBC::Connector::registerConnector();
|
||||
#endif
|
||||
}
|
||||
@ -139,7 +139,7 @@ DictionarySourcePtr DictionarySourceFactory::create(
|
||||
}
|
||||
else if ("mongodb" == source_type)
|
||||
{
|
||||
#if Poco_MongoDB_FOUND
|
||||
#if USE_POCO_MONGODB
|
||||
return std::make_unique<MongoDBDictionarySource>(dict_struct, config, config_prefix + ".mongodb", sample_block);
|
||||
#else
|
||||
throw Exception{"Dictionary source of type `mongodb` is disabled because poco library was built without mongodb support.",
|
||||
@ -148,7 +148,7 @@ DictionarySourcePtr DictionarySourceFactory::create(
|
||||
}
|
||||
else if ("odbc" == source_type)
|
||||
{
|
||||
#if Poco_SQLODBC_FOUND || Poco_DataODBC_FOUND
|
||||
#if USE_POCO_SQLODBC || USE_POCO_DATAODBC
|
||||
return std::make_unique<ODBCDictionarySource>(dict_struct, config, config_prefix + ".odbc", sample_block, context);
|
||||
#else
|
||||
throw Exception{"Dictionary source of type `odbc` is disabled because poco library was built without ODBC support.",
|
||||
@ -168,7 +168,7 @@ DictionarySourcePtr DictionarySourceFactory::create(
|
||||
if (dict_struct.has_expressions)
|
||||
throw Exception{"Dictionary source of type `http` does not support attribute expressions", ErrorCodes::LOGICAL_ERROR};
|
||||
|
||||
#if Poco_NetSSL_FOUND
|
||||
#if USE_POCO_NETSSL
|
||||
// Used for https queries
|
||||
std::call_once(ssl_init_once, SSLInit);
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <Common/config.h>
|
||||
#if Poco_MongoDB_FOUND
|
||||
#if USE_POCO_MONGODB
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <Common/config.h>
|
||||
#if Poco_MongoDB_FOUND
|
||||
#if USE_POCO_MONGODB
|
||||
#include <Poco/Util/AbstractConfiguration.h>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
|
||||
String getName() const override { return "MySQL"; }
|
||||
|
||||
Block getHeader() const override { return description.sample_block; };
|
||||
Block getHeader() const override { return description.sample_block; }
|
||||
|
||||
private:
|
||||
Block readImpl() override;
|
||||
|
@ -109,3 +109,7 @@ endif ()
|
||||
if (ENABLE_TESTS)
|
||||
add_subdirectory (tests)
|
||||
endif ()
|
||||
|
||||
if (USE_EMBEDDED_COMPILER)
|
||||
target_include_directories (clickhouse_functions BEFORE PUBLIC ${LLVM_INCLUDE_DIRS})
|
||||
endif ()
|
||||
|
@ -5,12 +5,16 @@
|
||||
#include <Columns/ColumnNullable.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include "FunctionsArithmetic.h"
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
}
|
||||
|
||||
const ColumnConst * checkAndGetColumnConstStringOrFixedString(const IColumn * column)
|
||||
{
|
||||
if (!column->isColumnConst())
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <DataTypes/DataTypeDate.h>
|
||||
#include <DataTypes/DataTypeDateTime.h>
|
||||
#include <DataTypes/DataTypeInterval.h>
|
||||
#include <DataTypes/Native.h>
|
||||
#include <Columns/ColumnVector.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
#include <Functions/IFunction.h>
|
||||
@ -17,7 +18,14 @@
|
||||
#include <Interpreters/ExpressionActions.h>
|
||||
#include <ext/range.h>
|
||||
#include <common/intExp.h>
|
||||
#include <boost/math/common_factor.hpp>
|
||||
#include <boost/integer/common_factor.hpp>
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -106,6 +114,15 @@ struct PlusImpl
|
||||
/// Next everywhere, static_cast - so that there is no wrong result in expressions of the form Int64 c = UInt32(a) * Int32(-1).
|
||||
return static_cast<Result>(a) + b;
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool)
|
||||
{
|
||||
return left->getType()->isIntegerTy() ? b.CreateAdd(left, right) : b.CreateFAdd(left, right);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -119,6 +136,15 @@ struct MultiplyImpl
|
||||
{
|
||||
return static_cast<Result>(a) * b;
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool)
|
||||
{
|
||||
return left->getType()->isIntegerTy() ? b.CreateMul(left, right) : b.CreateFMul(left, right);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -131,6 +157,15 @@ struct MinusImpl
|
||||
{
|
||||
return static_cast<Result>(a) - b;
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool)
|
||||
{
|
||||
return left->getType()->isIntegerTy() ? b.CreateSub(left, right) : b.CreateFSub(left, right);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -143,6 +178,17 @@ struct DivideFloatingImpl
|
||||
{
|
||||
return static_cast<Result>(a) / b;
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool)
|
||||
{
|
||||
if (left->getType()->isIntegerTy())
|
||||
throw Exception("DivideFloatingImpl expected a floating-point type", ErrorCodes::LOGICAL_ERROR);
|
||||
return b.CreateFDiv(left, right);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -189,6 +235,10 @@ struct DivideIntegralImpl
|
||||
throwIfDivisionLeadsToFPE(a, b);
|
||||
return a / b;
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false; /// don't know how to throw from LLVM IR
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -201,6 +251,10 @@ struct DivideIntegralOrZeroImpl
|
||||
{
|
||||
return unlikely(divisionLeadsToFPE(a, b)) ? 0 : a / b;
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false; /// TODO implement the checks
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -212,9 +266,12 @@ struct ModuloImpl
|
||||
static inline Result apply(A a, B b)
|
||||
{
|
||||
throwIfDivisionLeadsToFPE(typename NumberTraits::ToInteger<A>::Type(a), typename NumberTraits::ToInteger<B>::Type(b));
|
||||
return typename NumberTraits::ToInteger<A>::Type(a)
|
||||
% typename NumberTraits::ToInteger<B>::Type(b);
|
||||
return typename NumberTraits::ToInteger<A>::Type(a) % typename NumberTraits::ToInteger<B>::Type(b);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false; /// don't know how to throw from LLVM IR
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -225,9 +282,19 @@ struct BitAndImpl
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
{
|
||||
return static_cast<Result>(a)
|
||||
& static_cast<Result>(b);
|
||||
return static_cast<Result>(a) & static_cast<Result>(b);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool)
|
||||
{
|
||||
if (!left->getType()->isIntegerTy())
|
||||
throw Exception("BitAndImpl expected an integral type", ErrorCodes::LOGICAL_ERROR);
|
||||
return b.CreateAnd(left, right);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -238,9 +305,19 @@ struct BitOrImpl
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
{
|
||||
return static_cast<Result>(a)
|
||||
| static_cast<Result>(b);
|
||||
return static_cast<Result>(a) | static_cast<Result>(b);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool)
|
||||
{
|
||||
if (!left->getType()->isIntegerTy())
|
||||
throw Exception("BitOrImpl expected an integral type", ErrorCodes::LOGICAL_ERROR);
|
||||
return b.CreateOr(left, right);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -251,9 +328,19 @@ struct BitXorImpl
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
{
|
||||
return static_cast<Result>(a)
|
||||
^ static_cast<Result>(b);
|
||||
return static_cast<Result>(a) ^ static_cast<Result>(b);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool)
|
||||
{
|
||||
if (!left->getType()->isIntegerTy())
|
||||
throw Exception("BitXorImpl expected an integral type", ErrorCodes::LOGICAL_ERROR);
|
||||
return b.CreateXor(left, right);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -264,9 +351,19 @@ struct BitShiftLeftImpl
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
{
|
||||
return static_cast<Result>(a)
|
||||
<< static_cast<Result>(b);
|
||||
return static_cast<Result>(a) << static_cast<Result>(b);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool)
|
||||
{
|
||||
if (!left->getType()->isIntegerTy())
|
||||
throw Exception("BitShiftLeftImpl expected an integral type", ErrorCodes::LOGICAL_ERROR);
|
||||
return b.CreateShl(left, right);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -277,9 +374,19 @@ struct BitShiftRightImpl
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
{
|
||||
return static_cast<Result>(a)
|
||||
>> static_cast<Result>(b);
|
||||
return static_cast<Result>(a) >> static_cast<Result>(b);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool is_signed)
|
||||
{
|
||||
if (!left->getType()->isIntegerTy())
|
||||
throw Exception("BitShiftRightImpl expected an integral type", ErrorCodes::LOGICAL_ERROR);
|
||||
return is_signed ? b.CreateAShr(left, right) : b.CreateLShr(left, right);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -293,6 +400,19 @@ struct BitRotateLeftImpl
|
||||
return (static_cast<Result>(a) << static_cast<Result>(b))
|
||||
| (static_cast<Result>(a) >> ((sizeof(Result) * 8) - static_cast<Result>(b)));
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool)
|
||||
{
|
||||
if (!left->getType()->isIntegerTy())
|
||||
throw Exception("BitRotateLeftImpl expected an integral type", ErrorCodes::LOGICAL_ERROR);
|
||||
auto * size = llvm::ConstantInt::get(left->getType(), left->getType()->getPrimitiveSizeInBits());
|
||||
/// XXX how is this supposed to behave in signed mode?
|
||||
return b.CreateOr(b.CreateShl(left, right), b.CreateLShr(left, b.CreateSub(size, right)));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -306,24 +426,35 @@ struct BitRotateRightImpl
|
||||
return (static_cast<Result>(a) >> static_cast<Result>(b))
|
||||
| (static_cast<Result>(a) << ((sizeof(Result) * 8) - static_cast<Result>(b)));
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool)
|
||||
{
|
||||
if (!left->getType()->isIntegerTy())
|
||||
throw Exception("BitRotateRightImpl expected an integral type", ErrorCodes::LOGICAL_ERROR);
|
||||
auto * size = llvm::ConstantInt::get(left->getType(), left->getType()->getPrimitiveSizeInBits());
|
||||
return b.CreateOr(b.CreateLShr(left, right), b.CreateShl(left, b.CreateSub(size, right)));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_integral_v<T>, T> toInteger(T x) { return x; }
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_floating_point_v<T>, Int64> toInteger(T x) { return Int64(x); }
|
||||
|
||||
template <typename A, typename B>
|
||||
struct BitTestImpl
|
||||
{
|
||||
using ResultType = UInt8;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b) { return (toInteger(a) >> toInteger(b)) & 1; };
|
||||
};
|
||||
static inline Result apply(A a, B b)
|
||||
{
|
||||
return (typename NumberTraits::ToInteger<A>::Type(a) >> typename NumberTraits::ToInteger<B>::Type(b)) & 1;
|
||||
};
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false; /// TODO
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
struct LeastBaseImpl
|
||||
@ -336,6 +467,18 @@ struct LeastBaseImpl
|
||||
/** gcc 4.9.2 successfully vectorizes a loop from this function. */
|
||||
return static_cast<Result>(a) < static_cast<Result>(b) ? static_cast<Result>(a) : static_cast<Result>(b);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool is_signed)
|
||||
{
|
||||
if (!left->getType()->isIntegerTy())
|
||||
/// XXX minnum is basically fmin(), it may or may not match whatever apply() does
|
||||
return b.CreateMinNum(left, right);
|
||||
return b.CreateSelect(is_signed ? b.CreateICmpSLT(left, right) : b.CreateICmpULT(left, right), left, right);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -349,6 +492,10 @@ struct LeastSpecialImpl
|
||||
static_assert(std::is_same_v<Result, ResultType>, "ResultType != Result");
|
||||
return accurate::lessOp(a, b) ? static_cast<Result>(a) : static_cast<Result>(b);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false; /// ???
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -365,6 +512,19 @@ struct GreatestBaseImpl
|
||||
{
|
||||
return static_cast<Result>(a) > static_cast<Result>(b) ? static_cast<Result>(a) : static_cast<Result>(b);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool is_signed)
|
||||
{
|
||||
if (!left->getType()->isIntegerTy())
|
||||
/// XXX maxnum is basically fmax(), it may or may not match whatever apply() does
|
||||
/// XXX CreateMaxNum is broken on LLVM 5.0 and 6.0 (generates minnum instead; fixed in 7)
|
||||
return b.CreateBinaryIntrinsic(llvm::Intrinsic::maxnum, left, right);
|
||||
return b.CreateSelect(is_signed ? b.CreateICmpSGT(left, right) : b.CreateICmpUGT(left, right), left, right);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -378,6 +538,10 @@ struct GreatestSpecialImpl
|
||||
static_assert(std::is_same_v<Result, ResultType>, "ResultType != Result");
|
||||
return accurate::greaterOp(a, b) ? static_cast<Result>(a) : static_cast<Result>(b);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false; /// ???
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -393,6 +557,15 @@ struct NegateImpl
|
||||
{
|
||||
return -static_cast<ResultType>(a);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * arg, bool)
|
||||
{
|
||||
return arg->getType()->isIntegerTy() ? b.CreateNeg(arg) : b.CreateFNeg(arg);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A>
|
||||
@ -404,6 +577,17 @@ struct BitNotImpl
|
||||
{
|
||||
return ~static_cast<ResultType>(a);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * arg, bool)
|
||||
{
|
||||
if (!arg->getType()->isIntegerTy())
|
||||
throw Exception("BitNotImpl expected an integral type", ErrorCodes::LOGICAL_ERROR);
|
||||
return b.CreateNot(arg);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A>
|
||||
@ -420,6 +604,10 @@ struct AbsImpl
|
||||
else if constexpr (std::is_floating_point_v<A>)
|
||||
return static_cast<ResultType>(std::abs(a));
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false; /// special type handling, some other time
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -432,10 +620,14 @@ struct GCDImpl
|
||||
{
|
||||
throwIfDivisionLeadsToFPE(typename NumberTraits::ToInteger<A>::Type(a), typename NumberTraits::ToInteger<B>::Type(b));
|
||||
throwIfDivisionLeadsToFPE(typename NumberTraits::ToInteger<B>::Type(b), typename NumberTraits::ToInteger<A>::Type(a));
|
||||
return boost::math::gcd(
|
||||
return boost::integer::gcd(
|
||||
typename NumberTraits::ToInteger<Result>::Type(a),
|
||||
typename NumberTraits::ToInteger<Result>::Type(b));
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false; /// exceptions (and a non-trivial algorithm)
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
@ -448,10 +640,14 @@ struct LCMImpl
|
||||
{
|
||||
throwIfDivisionLeadsToFPE(typename NumberTraits::ToInteger<A>::Type(a), typename NumberTraits::ToInteger<B>::Type(b));
|
||||
throwIfDivisionLeadsToFPE(typename NumberTraits::ToInteger<B>::Type(b), typename NumberTraits::ToInteger<A>::Type(a));
|
||||
return boost::math::lcm(
|
||||
return boost::integer::lcm(
|
||||
typename NumberTraits::ToInteger<Result>::Type(a),
|
||||
typename NumberTraits::ToInteger<Result>::Type(b));
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false; /// exceptions (and a non-trivial algorithm)
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A>
|
||||
@ -463,6 +659,17 @@ struct IntExp2Impl
|
||||
{
|
||||
return intExp2(a);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = true;
|
||||
|
||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * arg, bool)
|
||||
{
|
||||
if (!arg->getType()->isIntegerTy())
|
||||
throw Exception("IntExp2Impl expected an integral type", ErrorCodes::LOGICAL_ERROR);
|
||||
return b.CreateShl(llvm::ConstantInt::get(arg->getType(), 1), arg);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A>
|
||||
@ -474,6 +681,10 @@ struct IntExp10Impl
|
||||
{
|
||||
return intExp10(a);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false; /// library function
|
||||
#endif
|
||||
};
|
||||
|
||||
/// Used to indicate undefined operation
|
||||
@ -745,6 +956,43 @@ public:
|
||||
if (!valid)
|
||||
throw Exception(getName() + "'s arguments do not match the expected data types", ErrorCodes::LOGICAL_ERROR);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
bool isCompilableImpl(const DataTypes & arguments) const override
|
||||
{
|
||||
return castBothTypes(arguments[0].get(), arguments[1].get(), [&](const auto & left, const auto & right)
|
||||
{
|
||||
using LeftDataType = std::decay_t<decltype(left)>;
|
||||
using RightDataType = std::decay_t<decltype(right)>;
|
||||
using ResultDataType = typename BinaryOperationTraits<Op, LeftDataType, RightDataType>::ResultDataType;
|
||||
using OpSpec = Op<typename LeftDataType::FieldType, typename RightDataType::FieldType>;
|
||||
return !std::is_same_v<ResultDataType, InvalidType> && OpSpec::compilable;
|
||||
});
|
||||
}
|
||||
|
||||
llvm::Value * compileImpl(llvm::IRBuilderBase & builder, const DataTypes & types, ValuePlaceholders values) const override
|
||||
{
|
||||
llvm::Value * result = nullptr;
|
||||
castBothTypes(types[0].get(), types[1].get(), [&](const auto & left, const auto & right)
|
||||
{
|
||||
using LeftDataType = std::decay_t<decltype(left)>;
|
||||
using RightDataType = std::decay_t<decltype(right)>;
|
||||
using ResultDataType = typename BinaryOperationTraits<Op, LeftDataType, RightDataType>::ResultDataType;
|
||||
using OpSpec = Op<typename LeftDataType::FieldType, typename RightDataType::FieldType>;
|
||||
if constexpr (!std::is_same_v<ResultDataType, InvalidType> && OpSpec::compilable)
|
||||
{
|
||||
auto & b = static_cast<llvm::IRBuilder<> &>(builder);
|
||||
auto type = std::make_shared<ResultDataType>();
|
||||
auto * lval = nativeCast(b, types[0], values[0](), type);
|
||||
auto * rval = nativeCast(b, types[1], values[1](), type);
|
||||
result = OpSpec::compile(b, lval, rval, std::is_signed_v<typename ResultDataType::FieldType>);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -821,6 +1069,35 @@ public:
|
||||
throw Exception(getName() + "'s argument does not match the expected data type", ErrorCodes::LOGICAL_ERROR);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
bool isCompilableImpl(const DataTypes & arguments) const override
|
||||
{
|
||||
return castType(arguments[0].get(), [&](const auto & type)
|
||||
{
|
||||
return Op<typename std::decay_t<decltype(type)>::FieldType>::compilable;
|
||||
});
|
||||
}
|
||||
|
||||
llvm::Value * compileImpl(llvm::IRBuilderBase & builder, const DataTypes & types, ValuePlaceholders values) const override
|
||||
{
|
||||
llvm::Value * result = nullptr;
|
||||
castType(types[0].get(), [&](const auto & type)
|
||||
{
|
||||
using T0 = typename std::decay_t<decltype(type)>::FieldType;
|
||||
using T1 = typename Op<T0>::ResultType;
|
||||
if constexpr (Op<T0>::compilable)
|
||||
{
|
||||
auto & b = static_cast<llvm::IRBuilder<> &>(builder);
|
||||
auto * v = nativeCast(b, types[0], values[0](), std::make_shared<DataTypeNumber<T1>>());
|
||||
result = Op<T0>::compile(b, v, std::is_signed_v<T1>);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool hasInformationAboutMonotonicity() const override
|
||||
{
|
||||
return FunctionUnaryArithmeticMonotonicity<Name>::has();
|
||||
|
@ -53,12 +53,26 @@ template <typename A, typename B> struct EqualsOp
|
||||
using SymmetricOp = EqualsOp<B, A>;
|
||||
|
||||
static UInt8 apply(A a, B b) { return accurate::equalsOp(a, b); }
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * x, llvm::Value * y, bool /*is_signed*/)
|
||||
{
|
||||
return x->getType()->isIntegerTy() ? b.CreateICmpEQ(x, y) : b.CreateFCmpOEQ(x, y); /// qNaNs always compare false
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B> struct NotEqualsOp
|
||||
{
|
||||
using SymmetricOp = NotEqualsOp<B, A>;
|
||||
static UInt8 apply(A a, B b) { return accurate::notEqualsOp(a, b); }
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * x, llvm::Value * y, bool /*is_signed*/)
|
||||
{
|
||||
return x->getType()->isIntegerTy() ? b.CreateICmpNE(x, y) : b.CreateFCmpONE(x, y);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B> struct GreaterOp;
|
||||
@ -67,12 +81,26 @@ template <typename A, typename B> struct LessOp
|
||||
{
|
||||
using SymmetricOp = GreaterOp<B, A>;
|
||||
static UInt8 apply(A a, B b) { return accurate::lessOp(a, b); }
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * x, llvm::Value * y, bool is_signed)
|
||||
{
|
||||
return x->getType()->isIntegerTy() ? (is_signed ? b.CreateICmpSLT(x, y) : b.CreateICmpULT(x, y)) : b.CreateFCmpOLT(x, y);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B> struct GreaterOp
|
||||
{
|
||||
using SymmetricOp = LessOp<B, A>;
|
||||
static UInt8 apply(A a, B b) { return accurate::greaterOp(a, b); }
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * x, llvm::Value * y, bool is_signed)
|
||||
{
|
||||
return x->getType()->isIntegerTy() ? (is_signed ? b.CreateICmpSGT(x, y) : b.CreateICmpUGT(x, y)) : b.CreateFCmpOGT(x, y);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B> struct GreaterOrEqualsOp;
|
||||
@ -81,12 +109,26 @@ template <typename A, typename B> struct LessOrEqualsOp
|
||||
{
|
||||
using SymmetricOp = GreaterOrEqualsOp<B, A>;
|
||||
static UInt8 apply(A a, B b) { return accurate::lessOrEqualsOp(a, b); }
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * x, llvm::Value * y, bool is_signed)
|
||||
{
|
||||
return x->getType()->isIntegerTy() ? (is_signed ? b.CreateICmpSLE(x, y) : b.CreateICmpULE(x, y)) : b.CreateFCmpOLE(x, y);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B> struct GreaterOrEqualsOp
|
||||
{
|
||||
using SymmetricOp = LessOrEqualsOp<B, A>;
|
||||
static UInt8 apply(A a, B b) { return accurate::greaterOrEqualsOp(a, b); }
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * x, llvm::Value * y, bool is_signed)
|
||||
{
|
||||
return x->getType()->isIntegerTy() ? (is_signed ? b.CreateICmpSGE(x, y) : b.CreateICmpUGE(x, y)) : b.CreateFCmpOGE(x, y);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -1136,6 +1178,41 @@ public:
|
||||
col_with_type_and_name_left.type, col_with_type_and_name_right.type,
|
||||
left_is_num, input_rows_count);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
bool isCompilableImpl(const DataTypes & types) const override
|
||||
{
|
||||
auto isBigInteger = &typeIsEither<DataTypeInt64, DataTypeUInt64, DataTypeUUID>;
|
||||
auto isFloatingPoint = &typeIsEither<DataTypeFloat32, DataTypeFloat64>;
|
||||
if ((isBigInteger(*types[0]) && isFloatingPoint(*types[1])) || (isBigInteger(*types[1]) && isFloatingPoint(*types[0])))
|
||||
return false; /// TODO: implement (double, int_N where N > double's mantissa width)
|
||||
return types[0]->isValueRepresentedByNumber() && types[1]->isValueRepresentedByNumber();
|
||||
}
|
||||
|
||||
llvm::Value * compileImpl(llvm::IRBuilderBase & builder, const DataTypes & types, ValuePlaceholders values) const override
|
||||
{
|
||||
auto & b = static_cast<llvm::IRBuilder<> &>(builder);
|
||||
auto * x = values[0]();
|
||||
auto * y = values[1]();
|
||||
if (!types[0]->equals(*types[1]))
|
||||
{
|
||||
llvm::Type * common;
|
||||
if (x->getType()->isIntegerTy() && y->getType()->isIntegerTy())
|
||||
common = b.getIntNTy(std::max(
|
||||
/// if one integer has a sign bit, make sure the other does as well. llvm generates optimal code
|
||||
/// (e.g. uses overflow flag on x86) for (word size + 1)-bit integer operations.
|
||||
x->getType()->getIntegerBitWidth() + (!typeIsSigned(*types[0]) && typeIsSigned(*types[1])),
|
||||
y->getType()->getIntegerBitWidth() + (!typeIsSigned(*types[1]) && typeIsSigned(*types[0]))));
|
||||
else
|
||||
/// (double, float) or (double, int_N where N <= double's mantissa width) -> double
|
||||
common = b.getDoubleTy();
|
||||
x = nativeCast(b, types[0], x, common);
|
||||
y = nativeCast(b, types[1], y, common);
|
||||
}
|
||||
auto * result = Op<int, int>::compile(b, x, y, typeIsSigned(*types[0]) || typeIsSigned(*types[1]));
|
||||
return b.CreateSelect(result, b.getInt8(1), b.getInt8(0));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <DataTypes/DataTypeFixedString.h>
|
||||
#include <DataTypes/DataTypeTuple.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
#include <DataTypes/Native.h>
|
||||
#include <Columns/ColumnVector.h>
|
||||
#include <Columns/ColumnString.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
@ -113,7 +114,65 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class FunctionIf : public IFunction
|
||||
template <bool null_is_false>
|
||||
class FunctionIfBase : public IFunction
|
||||
{
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
public:
|
||||
bool isCompilableImpl(const DataTypes & types) const override
|
||||
{
|
||||
for (const auto & type : types)
|
||||
if (!removeNullable(type)->isValueRepresentedByNumber())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
llvm::Value * compileImpl(llvm::IRBuilderBase & builder, const DataTypes & types, ValuePlaceholders values) const override
|
||||
{
|
||||
auto & b = static_cast<llvm::IRBuilder<> &>(builder);
|
||||
auto type = getReturnTypeImpl(types);
|
||||
llvm::Value * null = nullptr;
|
||||
if (!null_is_false && type->isNullable())
|
||||
null = b.CreateInsertValue(llvm::Constant::getNullValue(toNativeType(b, type)), b.getTrue(), {1});
|
||||
auto * head = b.GetInsertBlock();
|
||||
auto * join = llvm::BasicBlock::Create(head->getContext(), "", head->getParent());
|
||||
std::vector<std::pair<llvm::BasicBlock *, llvm::Value *>> returns;
|
||||
for (size_t i = 0; i + 1 < types.size(); i += 2)
|
||||
{
|
||||
auto * then = llvm::BasicBlock::Create(head->getContext(), "", head->getParent());
|
||||
auto * next = llvm::BasicBlock::Create(head->getContext(), "", head->getParent());
|
||||
auto * cond = values[i]();
|
||||
if (!null_is_false && types[i]->isNullable())
|
||||
{
|
||||
auto * nonnull = llvm::BasicBlock::Create(head->getContext(), "", head->getParent());
|
||||
returns.emplace_back(b.GetInsertBlock(), null);
|
||||
b.CreateCondBr(b.CreateExtractValue(cond, {1}), join, nonnull);
|
||||
b.SetInsertPoint(nonnull);
|
||||
b.CreateCondBr(nativeBoolCast(b, removeNullable(types[i]), b.CreateExtractValue(cond, {0})), then, next);
|
||||
}
|
||||
else
|
||||
{
|
||||
b.CreateCondBr(nativeBoolCast(b, types[i], cond), then, next);
|
||||
}
|
||||
b.SetInsertPoint(then);
|
||||
auto * value = nativeCast(b, types[i + 1], values[i + 1](), type);
|
||||
returns.emplace_back(b.GetInsertBlock(), value);
|
||||
b.CreateBr(join);
|
||||
b.SetInsertPoint(next);
|
||||
}
|
||||
auto * value = nativeCast(b, types.back(), values.back()(), type);
|
||||
returns.emplace_back(b.GetInsertBlock(), value);
|
||||
b.CreateBr(join);
|
||||
b.SetInsertPoint(join);
|
||||
auto * phi = b.CreatePHI(toNativeType(b, type), returns.size());
|
||||
for (const auto & r : returns)
|
||||
phi->addIncoming(r.second, r.first);
|
||||
return phi;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class FunctionIf : public FunctionIfBase</*null_is_false=*/false>
|
||||
{
|
||||
public:
|
||||
static constexpr auto name = "if";
|
||||
@ -916,8 +975,8 @@ public:
|
||||
/// - arrays of such types.
|
||||
///
|
||||
/// Additionally the arguments, conditions or branches, support nullable types
|
||||
/// and the NULL value.
|
||||
class FunctionMultiIf final : public IFunction
|
||||
/// and the NULL value, with a NULL condition treated as false.
|
||||
class FunctionMultiIf final : public FunctionIfBase</*null_is_false=*/true>
|
||||
{
|
||||
public:
|
||||
static constexpr auto name = "multiIf";
|
||||
|
@ -21,7 +21,7 @@ void throwExceptionForIncompletelyParsedValue(
|
||||
message_buf << " at begin of string";
|
||||
|
||||
if (to_type.isNumber())
|
||||
message_buf << ". Note: there are to" << to_type.getName() << "OrZero function, which returns zero instead of throwing exception.";
|
||||
message_buf << ". Note: there are to" << to_type.getName() << "OrZero and to" << to_type.getName() << "OrNull functions, which returns zero/NULL instead of throwing exception.";
|
||||
|
||||
throw Exception(message_buf.str(), ErrorCodes::CANNOT_PARSE_TEXT);
|
||||
}
|
||||
|
@ -12,6 +12,13 @@
|
||||
#include <Functions/FunctionHelpers.h>
|
||||
#include <type_traits>
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
@ -31,65 +38,71 @@ namespace ErrorCodes
|
||||
* For example, 1 OR NULL returns 1, not NULL.
|
||||
*/
|
||||
|
||||
|
||||
struct AndImpl
|
||||
{
|
||||
static inline bool isSaturable()
|
||||
static inline constexpr bool isSaturable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool isSaturatedValue(bool a)
|
||||
static inline constexpr bool isSaturatedValue(bool a)
|
||||
{
|
||||
return !a;
|
||||
}
|
||||
|
||||
static inline bool apply(bool a, bool b)
|
||||
static inline constexpr bool apply(bool a, bool b)
|
||||
{
|
||||
return a && b;
|
||||
}
|
||||
|
||||
static inline bool specialImplementationForNulls() { return false; }
|
||||
static inline constexpr bool specialImplementationForNulls() { return false; }
|
||||
};
|
||||
|
||||
struct OrImpl
|
||||
{
|
||||
static inline bool isSaturable()
|
||||
static inline constexpr bool isSaturable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool isSaturatedValue(bool a)
|
||||
static inline constexpr bool isSaturatedValue(bool a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline bool apply(bool a, bool b)
|
||||
static inline constexpr bool apply(bool a, bool b)
|
||||
{
|
||||
return a || b;
|
||||
}
|
||||
|
||||
static inline bool specialImplementationForNulls() { return true; }
|
||||
static inline constexpr bool specialImplementationForNulls() { return true; }
|
||||
};
|
||||
|
||||
struct XorImpl
|
||||
{
|
||||
static inline bool isSaturable()
|
||||
static inline constexpr bool isSaturable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool isSaturatedValue(bool)
|
||||
static inline constexpr bool isSaturatedValue(bool)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool apply(bool a, bool b)
|
||||
static inline constexpr bool apply(bool a, bool b)
|
||||
{
|
||||
return a != b;
|
||||
}
|
||||
|
||||
static inline bool specialImplementationForNulls() { return false; }
|
||||
static inline constexpr bool specialImplementationForNulls() { return false; }
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static inline llvm::Value * apply(llvm::IRBuilder<> & builder, llvm::Value * a, llvm::Value * b)
|
||||
{
|
||||
return builder.CreateXor(a, b);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A>
|
||||
@ -101,6 +114,13 @@ struct NotImpl
|
||||
{
|
||||
return !a;
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static inline llvm::Value * apply(llvm::IRBuilder<> & builder, llvm::Value * a)
|
||||
{
|
||||
return builder.CreateNot(a);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -364,6 +384,44 @@ public:
|
||||
|
||||
block.getByPosition(result).column = std::move(col_res);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
bool isCompilableImpl(const DataTypes &) const override { return true; }
|
||||
|
||||
llvm::Value * compileImpl(llvm::IRBuilderBase & builder, const DataTypes & types, ValuePlaceholders values) const override
|
||||
{
|
||||
auto & b = static_cast<llvm::IRBuilder<> &>(builder);
|
||||
if constexpr (!Impl::isSaturable())
|
||||
{
|
||||
auto * result = nativeBoolCast(b, types[0], values[0]());
|
||||
for (size_t i = 1; i < types.size(); i++)
|
||||
result = Impl::apply(b, result, nativeBoolCast(b, types[i], values[i]()));
|
||||
return b.CreateSelect(result, b.getInt8(1), b.getInt8(0));
|
||||
}
|
||||
constexpr bool breakOnTrue = Impl::isSaturatedValue(true);
|
||||
auto * next = b.GetInsertBlock();
|
||||
auto * stop = llvm::BasicBlock::Create(next->getContext(), "", next->getParent());
|
||||
b.SetInsertPoint(stop);
|
||||
auto * phi = b.CreatePHI(b.getInt8Ty(), values.size());
|
||||
for (size_t i = 0; i < types.size(); i++)
|
||||
{
|
||||
b.SetInsertPoint(next);
|
||||
auto * value = values[i]();
|
||||
auto * truth = nativeBoolCast(b, types[i], value);
|
||||
if (!types[i]->equals(DataTypeUInt8{}))
|
||||
value = b.CreateSelect(truth, b.getInt8(1), b.getInt8(0));
|
||||
phi->addIncoming(value, b.GetInsertBlock());
|
||||
if (i + 1 < types.size())
|
||||
{
|
||||
next = llvm::BasicBlock::Create(next->getContext(), "", next->getParent());
|
||||
b.CreateCondBr(truth, breakOnTrue ? stop : next, breakOnTrue ? next : stop);
|
||||
}
|
||||
}
|
||||
b.CreateBr(stop);
|
||||
b.SetInsertPoint(stop);
|
||||
return phi;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -430,6 +488,16 @@ public:
|
||||
+ " of argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
bool isCompilableImpl(const DataTypes &) const override { return true; }
|
||||
|
||||
llvm::Value * compileImpl(llvm::IRBuilderBase & builder, const DataTypes & types, ValuePlaceholders values) const override
|
||||
{
|
||||
auto & b = static_cast<llvm::IRBuilder<> &>(builder);
|
||||
return b.CreateSelect(Impl<UInt8>::apply(b, nativeBoolCast(b, types[0], values[0]())), b.getInt8(1), b.getInt8(0));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -755,7 +755,7 @@ public:
|
||||
tuple = typeid_cast<const ColumnTuple *>(materialized_tuple.get());
|
||||
}
|
||||
|
||||
if (tuple)
|
||||
if (tuple && type_tuple->getElements().size() != 1)
|
||||
{
|
||||
const Columns & tuple_columns = tuple->getColumns();
|
||||
const DataTypes & tuple_types = type_tuple->getElements();
|
||||
|
@ -93,6 +93,10 @@ struct RoundToExp2Impl
|
||||
{
|
||||
return roundDownToPowerOfTwo<T>(x);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -120,6 +124,10 @@ struct RoundDurationImpl
|
||||
: (x < 36000 ? 18000
|
||||
: 36000))))))))))))));
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A>
|
||||
@ -137,6 +145,10 @@ struct RoundAgeImpl
|
||||
: (x < 55 ? 45
|
||||
: 55)))));
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,15 +1,25 @@
|
||||
#include <Functions/IFunction.h>
|
||||
#include <Functions/FunctionHelpers.h>
|
||||
#include <Columns/ColumnNullable.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
#include <DataTypes/DataTypeNothing.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
#include <Interpreters/ExpressionActions.h>
|
||||
#include <Common/config.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
#include <Columns/ColumnNullable.h>
|
||||
#include <DataTypes/DataTypeNothing.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
#include <DataTypes/Native.h>
|
||||
#include <Functions/FunctionHelpers.h>
|
||||
#include <Functions/IFunction.h>
|
||||
#include <Interpreters/ExpressionActions.h>
|
||||
#include <ext/range.h>
|
||||
#include <ext/collection_cast.h>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -21,6 +31,7 @@ namespace ErrorCodes
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
@ -259,4 +270,71 @@ DataTypePtr FunctionBuilderImpl::getReturnType(const ColumnsWithTypeAndName & ar
|
||||
|
||||
return getReturnTypeImpl(arguments);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
|
||||
static std::optional<DataTypes> removeNullables(const DataTypes & types)
|
||||
{
|
||||
for (const auto & type : types)
|
||||
{
|
||||
if (!typeid_cast<const DataTypeNullable *>(type.get()))
|
||||
continue;
|
||||
DataTypes filtered;
|
||||
for (const auto & type : types)
|
||||
filtered.emplace_back(removeNullable(type));
|
||||
return filtered;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool IFunction::isCompilable(const DataTypes & arguments) const
|
||||
{
|
||||
if (useDefaultImplementationForNulls())
|
||||
if (auto denulled = removeNullables(arguments))
|
||||
return isCompilableImpl(*denulled);
|
||||
return isCompilableImpl(arguments);
|
||||
}
|
||||
|
||||
llvm::Value * IFunction::compile(llvm::IRBuilderBase & builder, const DataTypes & arguments, ValuePlaceholders values) const
|
||||
{
|
||||
if (useDefaultImplementationForNulls())
|
||||
{
|
||||
if (auto denulled = removeNullables(arguments))
|
||||
{
|
||||
/// FIXME: when only one column is nullable, this can actually be slower than the non-jitted version
|
||||
/// because this involves copying the null map while `wrapInNullable` reuses it.
|
||||
auto & b = static_cast<llvm::IRBuilder<> &>(builder);
|
||||
auto * fail = llvm::BasicBlock::Create(b.GetInsertBlock()->getContext(), "", b.GetInsertBlock()->getParent());
|
||||
auto * join = llvm::BasicBlock::Create(b.GetInsertBlock()->getContext(), "", b.GetInsertBlock()->getParent());
|
||||
auto * zero = llvm::Constant::getNullValue(toNativeType(b, makeNullable(getReturnTypeImpl(*denulled))));
|
||||
for (size_t i = 0; i < arguments.size(); i++)
|
||||
{
|
||||
if (!arguments[i]->isNullable())
|
||||
continue;
|
||||
/// Would be nice to evaluate all this lazily, but that'd change semantics: if only unevaluated
|
||||
/// arguments happen to contain NULLs, the return value would not be NULL, though it should be.
|
||||
auto * value = values[i]();
|
||||
auto * ok = llvm::BasicBlock::Create(b.GetInsertBlock()->getContext(), "", b.GetInsertBlock()->getParent());
|
||||
b.CreateCondBr(b.CreateExtractValue(value, {1}), fail, ok);
|
||||
b.SetInsertPoint(ok);
|
||||
values[i] = [value = b.CreateExtractValue(value, {0})]() { return value; };
|
||||
}
|
||||
auto * result = b.CreateInsertValue(zero, compileImpl(builder, *denulled, std::move(values)), {0});
|
||||
auto * result_block = b.GetInsertBlock();
|
||||
b.CreateBr(join);
|
||||
b.SetInsertPoint(fail);
|
||||
auto * null = b.CreateInsertValue(zero, b.getTrue(), {1});
|
||||
b.CreateBr(join);
|
||||
b.SetInsertPoint(join);
|
||||
auto * phi = b.CreatePHI(result->getType(), 2);
|
||||
phi->addIncoming(result, result_block);
|
||||
phi->addIncoming(null, fail);
|
||||
return phi;
|
||||
}
|
||||
}
|
||||
return compileImpl(builder, arguments, std::move(values));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <Common/config.h>
|
||||
#include <Core/Names.h>
|
||||
#include <Core/Field.h>
|
||||
#include <Core/Block.h>
|
||||
@ -9,6 +10,14 @@
|
||||
#include <DataTypes/IDataType.h>
|
||||
|
||||
|
||||
namespace llvm
|
||||
{
|
||||
class LLVMContext;
|
||||
class Value;
|
||||
class IRBuilderBase;
|
||||
}
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
@ -70,6 +79,8 @@ private:
|
||||
size_t input_rows_count);
|
||||
};
|
||||
|
||||
using ValuePlaceholders = std::vector<std::function<llvm::Value * ()>>;
|
||||
|
||||
/// Function with known arguments and return type.
|
||||
class IFunctionBase
|
||||
{
|
||||
@ -92,6 +103,25 @@ public:
|
||||
return prepare(block)->execute(block, arguments, result, input_rows_count);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
|
||||
virtual bool isCompilable() const { return false; }
|
||||
|
||||
/** Produce LLVM IR code that operates on scalar values. See `toNativeType` in DataTypes/Native.h
|
||||
* for supported value types and how they map to LLVM types.
|
||||
*
|
||||
* NOTE: the builder is actually guaranteed to be exactly `llvm::IRBuilder<>`, so you may safely
|
||||
* downcast it to that type. This method is specified with `IRBuilderBase` because forward-declaring
|
||||
* templates with default arguments is impossible and including LLVM in such a generic header
|
||||
* as this one is a major pain.
|
||||
*/
|
||||
virtual llvm::Value * compile(llvm::IRBuilderBase & /*builder*/, ValuePlaceholders /*values*/) const
|
||||
{
|
||||
throw Exception(getName() + " is not JIT-compilable", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/** Should we evaluate this function while constant folding, if arguments are constants?
|
||||
* Usually this is true. Notable counterexample is function 'sleep'.
|
||||
* If we will call it during query analysis, we will sleep extra amount of time.
|
||||
@ -261,7 +291,6 @@ public:
|
||||
using PreparedFunctionImpl::execute;
|
||||
using FunctionBuilderImpl::getReturnTypeImpl;
|
||||
using FunctionBuilderImpl::getLambdaArgumentTypesImpl;
|
||||
|
||||
using FunctionBuilderImpl::getReturnType;
|
||||
|
||||
PreparedFunctionPtr prepare(const Block & /*sample_block*/) const final
|
||||
@ -269,17 +298,51 @@ public:
|
||||
throw Exception("prepare is not implemented for IFunction", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
|
||||
bool isCompilable() const final
|
||||
{
|
||||
throw Exception("isCompilable without explicit types is not implemented for IFunction", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
llvm::Value * compile(llvm::IRBuilderBase & /*builder*/, ValuePlaceholders /*values*/) const final
|
||||
{
|
||||
throw Exception("compile without explicit types is not implemented for IFunction", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const DataTypes & getArgumentTypes() const final
|
||||
{
|
||||
throw Exception("getArgumentTypes is not implemented for IFunction", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
const DataTypePtr & getReturnType() const override
|
||||
const DataTypePtr & getReturnType() const final
|
||||
{
|
||||
throw Exception("getReturnType is not implemented for IFunction", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
|
||||
bool isCompilable(const DataTypes & arguments) const;
|
||||
|
||||
llvm::Value * compile(llvm::IRBuilderBase &, const DataTypes & arguments, ValuePlaceholders values) const;
|
||||
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
|
||||
virtual bool isCompilableImpl(const DataTypes &) const { return false; }
|
||||
|
||||
virtual llvm::Value * compileImpl(llvm::IRBuilderBase &, const DataTypes &, ValuePlaceholders) const
|
||||
{
|
||||
throw Exception(getName() + " is not JIT-compilable", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
FunctionBasePtr buildImpl(const ColumnsWithTypeAndName & /*arguments*/, const DataTypePtr & /*return_type*/) const final
|
||||
{
|
||||
throw Exception("buildImpl is not implemented for IFunction", ErrorCodes::NOT_IMPLEMENTED);
|
||||
@ -319,6 +382,14 @@ public:
|
||||
const DataTypes & getArgumentTypes() const override { return arguments; }
|
||||
const DataTypePtr & getReturnType() const override { return return_type; }
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
|
||||
bool isCompilable() const override { return function->isCompilable(arguments); }
|
||||
|
||||
llvm::Value * compile(llvm::IRBuilderBase & builder, ValuePlaceholders values) const override { return function->compile(builder, arguments, std::move(values)); }
|
||||
|
||||
#endif
|
||||
|
||||
PreparedFunctionPtr prepare(const Block & /*sample_block*/) const override { return std::make_shared<DefaultExecutable>(function); }
|
||||
|
||||
bool isSuitableForConstantFolding() const override { return function->isSuitableForConstantFolding(); }
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include <IO/HTTPCommon.h>
|
||||
|
||||
#include <Common/config.h>
|
||||
#if Poco_NetSSL_FOUND
|
||||
#if USE_POCO_NETSSL
|
||||
#include <Poco/Net/AcceptCertificateHandler.h>
|
||||
#include <Poco/Net/Context.h>
|
||||
#include <Poco/Net/InvalidCertificateHandler.h>
|
||||
@ -30,7 +30,7 @@ std::once_flag ssl_init_once;
|
||||
void SSLInit()
|
||||
{
|
||||
// http://stackoverflow.com/questions/18315472/https-request-in-c-using-poco
|
||||
#if Poco_NetSSL_FOUND
|
||||
#if USE_POCO_NETSSL
|
||||
Poco::Net::initializeSSL();
|
||||
#endif
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user