diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 905c0868..9f233f98 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -8,6 +8,11 @@ on: pull_request: branches: [ master ] + release: + types: + - published + - prereleased + env: BUILD_TYPE: Release CLICKHOUSE_SERVER_IMAGE: "clickhouse/clickhouse-server:22.3" @@ -65,54 +70,57 @@ jobs: runs-on: ${{matrix.os}} steps: - - uses: actions/checkout@v2 - - - name: Install dependencies - run: | - sudo apt-get update && \ - sudo apt-get install -y \ - docker \ + - uses: actions/checkout@v4 + with: + fetch-depth: 100 + fetch-tags: true + + - name: Install dependencies + run: | + sudo apt-get update && \ + sudo apt-get install -y \ + docker \ + cmake \ + ${{matrix.COMPILER_INSTALL}} \ + ${{matrix.DEPENDENCIES_INSTALL}} + + - name: Install dependencies - Docker + run: | + sudo apt remove -y docker docker-engine docker.io containerd runc + sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg + echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + sudo apt update -q + sudo apt install docker-ce docker-ce-cli containerd.io + + - name: Configure project + run: | + cmake \ + -D CMAKE_C_COMPILER=${{matrix.C_COMPILER}} \ + -D CMAKE_CXX_COMPILER=${{matrix.CXX_COMPILER}} \ + -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ + -D BUILD_TESTS=ON \ + ${{matrix.SSL_CMAKE_OPTION}} \ + ${{matrix.DEPENDENCIES_CMAKE_OPTIONS}} \ + -S ${{github.workspace}} \ + -B ${{github.workspace}}/build + + - name: Build project + run: | cmake \ - ${{matrix.COMPILER_INSTALL}} \ - ${{matrix.DEPENDENCIES_INSTALL}} - - - name: Install dependencies - Docker - run: | - sudo apt remove -y docker docker-engine docker.io containerd runc - sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg - echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null - sudo apt update -q - sudo apt install docker-ce docker-ce-cli containerd.io - - - name: Configure project - run: | - cmake \ - -D CMAKE_C_COMPILER=${{matrix.C_COMPILER}} \ - -D CMAKE_CXX_COMPILER=${{matrix.CXX_COMPILER}} \ - -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ - -D BUILD_TESTS=ON \ - ${{matrix.SSL_CMAKE_OPTION}} \ - ${{matrix.DEPENDENCIES_CMAKE_OPTIONS}} \ - -S ${{github.workspace}} \ - -B ${{github.workspace}}/build - - - name: Build project - run: | - cmake \ - --build ${{github.workspace}}/build \ - --config ${{env.BUILD_TYPE}} \ - --target all - - - name: Test - Start ClickHouse server in background - run: | - docker pull ${CLICKHOUSE_SERVER_IMAGE} - docker run -d --name clickhouse -p 9000:9000 ${CLICKHOUSE_SERVER_IMAGE} - docker ps -a - docker stats -a --no-stream - ## Check and wait until CH is ready to accept connections - docker exec clickhouse bash -c 'for i in {1..10}; do echo checking if clickhouse server is started attempt \#$i; if ( grep -q " Application: Ready for connections." /var/log/clickhouse-server/clickhouse-server.log ); then echo seems like clickhouse server is started; exit 0; fi; sleep 1; done; exit -1' - - - name: Test - working-directory: ${{github.workspace}}/build/ut - run: ./clickhouse-cpp-ut + --build ${{github.workspace}}/build \ + --config ${{env.BUILD_TYPE}} \ + --target all + + - name: Test - Start ClickHouse server in background + run: | + docker pull ${CLICKHOUSE_SERVER_IMAGE} + docker run -d --name clickhouse -p 9000:9000 ${CLICKHOUSE_SERVER_IMAGE} + docker ps -a + docker stats -a --no-stream + ## Check and wait until CH is ready to accept connections + docker exec clickhouse bash -c 'for i in {1..10}; do echo checking if clickhouse server is started attempt \#$i; if ( grep -q " Application: Ready for connections." /var/log/clickhouse-server/clickhouse-server.log ); then echo seems like clickhouse server is started; exit 0; fi; sleep 1; done; exit -1' + + - name: Test + working-directory: ${{github.workspace}}/build/ut + run: ./clickhouse-cpp-ut diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 215b2214..b3faae21 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -7,6 +7,10 @@ on: branches: [ master ] pull_request: branches: [ master ] + release: + types: + - published + - prereleased env: BUILD_TYPE: Release @@ -31,41 +35,44 @@ jobs: SSL_INSTALL: openssl steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + with: + fetch-depth: 100 + fetch-tags: true - - name: Install dependencies - run: brew install cmake ${{matrix.SSL_INSTALL}} + - name: Install dependencies + run: brew install cmake ${{matrix.SSL_INSTALL}} - - name: Configure CMake - run: | - cmake \ - -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ - -D BUILD_TESTS=ON \ - ${{matrix.SSL_CMAKE_OPTION}} \ - -S ${{github.workspace}} \ - -B ${{github.workspace}}/build + - name: Configure CMake + run: | + cmake \ + -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ + -D BUILD_TESTS=ON \ + ${{matrix.SSL_CMAKE_OPTION}} \ + -S ${{github.workspace}} \ + -B ${{github.workspace}}/build - - name: Build - run: | - cmake \ - --build ${{github.workspace}}/build \ - --config ${{env.BUILD_TYPE}} \ - --target all + - name: Build + run: | + cmake \ + --build ${{github.workspace}}/build \ + --config ${{env.BUILD_TYPE}} \ + --target all - - name: Start tls offoader proxy - # that mimics non-secure clickhouse running on localhost - # by tunneling queries to remote tls server - # (needed because we can't start real clickhouse instance on macOS) - run: | - wget https://github.com/filimonov/go-tlsoffloader/releases/download/v0.1.2/go-tlsoffloader_0.1.2_Darwin_x86_64.tar.gz - tar -xvzf go-tlsoffloader_0.1.2_Darwin_x86_64.tar.gz - ./go-tlsoffloader -l localhost:9000 -b github.demo.trial.altinity.cloud:9440 & + - name: Start tls offoader proxy + # that mimics non-secure clickhouse running on localhost + # by tunneling queries to remote tls server + # (needed because we can't start real clickhouse instance on macOS) + run: | + wget https://github.com/filimonov/go-tlsoffloader/releases/download/v0.1.2/go-tlsoffloader_0.1.2_Darwin_x86_64.tar.gz + tar -xvzf go-tlsoffloader_0.1.2_Darwin_x86_64.tar.gz + ./go-tlsoffloader -l localhost:9000 -b github.demo.trial.altinity.cloud:9440 & - - name: Test - working-directory: ${{github.workspace}}/build/ut - env: - # It is impossible to start CH server in docker on macOS due to github actions limitations, - # so we use remote server to execute tests, some do not allow some features for anonymoust/free users: - # - system.query_log used by 'Client/ClientCase.Query_ID' - GTEST_FILTER: "-Client/ClientCase.Query_ID*:Client/ClientCase.TracingContext/*" - run: ./clickhouse-cpp-ut ${GTEST_FILTER} + - name: Test + working-directory: ${{github.workspace}}/build/ut + env: + # It is impossible to start CH server in docker on macOS due to github actions limitations, + # so we use remote server to execute tests, some do not allow some features for anonymoust/free users: + # - system.query_log used by 'Client/ClientCase.Query_ID' + GTEST_FILTER: "-Client/ClientCase.Query_ID*:Client/ClientCase.TracingContext/*" + run: ./clickhouse-cpp-ut ${GTEST_FILTER} diff --git a/.github/workflows/windows_mingw.yml b/.github/workflows/windows_mingw.yml index 6c6c3e9b..5681c7c4 100644 --- a/.github/workflows/windows_mingw.yml +++ b/.github/workflows/windows_mingw.yml @@ -8,6 +8,11 @@ on: pull_request: branches: [ master ] + release: + types: + - published + - prereleased + env: BUILD_TYPE: Release CLICKHOUSE_USER: clickhouse_cpp_cicd @@ -49,44 +54,48 @@ jobs: shell: msys2 {0} steps: - - uses: actions/checkout@v2 - - uses: msys2/setup-msys2@v2 - with: - msystem: ${{ matrix.sys }} - update: true - install: >- - mingw-w64-${{matrix.env}}-cmake - mingw-w64-${{matrix.env}}-make - mingw-w64-${{matrix.env}}-gcc - mingw-w64-${{matrix.env}}-openssl - mingw-w64-${{matrix.env}}-ninja - mingw-w64-${{matrix.env}}-wget - mingw-w64-${{matrix.env}}-ca-certificates - tar + - uses: actions/checkout@v4 + with: + fetch-depth: 100 + fetch-tags: true + - uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.sys }} + update: true + install: >- + mingw-w64-${{matrix.env}}-cmake + mingw-w64-${{matrix.env}}-make + mingw-w64-${{matrix.env}}-gcc + mingw-w64-${{matrix.env}}-openssl + mingw-w64-${{matrix.env}}-ninja + mingw-w64-${{matrix.env}}-wget + mingw-w64-${{matrix.env}}-ca-certificates + tar - - name: Configure CMake - run: cmake -B build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBUILD_TESTS=ON - # -DWITH_OPENSSL=ON was not able to make it work (some strange issues with CA paths, need debug) + - name: Configure CMake + run: cmake -B build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBUILD_TESTS=ON -DCHECK_VERSION=OFF + # -DWITH_OPENSSL=ON was not able to make it work (some strange issues with CA paths, need debug) + # -DCHECK_VERSION=OFF since it requires git, which can't be found from within cmake for some reason. - - name: Build - run: cmake --build build --config ${{env.BUILD_TYPE}} --target all + - name: Build + run: cmake --build build --config ${{env.BUILD_TYPE}} --target all - - name: Start tls offoader proxy - # that mimics non-secure clickhouse running on localhost - # by tunneling queries to remote tls server - # (needed because we can't start real clickhouse instance on windows) - run: | - wget https://github.com/filimonov/go-tlsoffloader/releases/download/v0.1.2/go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz - tar -xvzf go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz - ./go-tlsoffloader.exe -l localhost:9000 -b github.demo.trial.altinity.cloud:9440 & + - name: Start tls offoader proxy + # that mimics non-secure clickhouse running on localhost + # by tunneling queries to remote tls server + # (needed because we can't start real clickhouse instance on windows) + run: | + wget https://github.com/filimonov/go-tlsoffloader/releases/download/v0.1.2/go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz + tar -xvzf go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz + ./go-tlsoffloader.exe -l localhost:9000 -b github.demo.trial.altinity.cloud:9440 & - - name: Test - env: - # It is impossible to start CH server in docker on Windows due to github actions limitations, - # so we use remote server to execute tests, some do not allow some features for anonymoust/free users: - # - system.query_log used by 'Client/ClientCase.Query_ID' - GTEST_FILTER: "-Client/ClientCase.Query_ID*:Client/ClientCase.TracingContext/*" - run: ./build/ut/clickhouse-cpp-ut.exe ${GTEST_FILTER} + - name: Test + env: + # It is impossible to start CH server in docker on Windows due to github actions limitations, + # so we use remote server to execute tests, some do not allow some features for anonymoust/free users: + # - system.query_log used by 'Client/ClientCase.Query_ID' + GTEST_FILTER: "-Client/ClientCase.Query_ID*:Client/ClientCase.TracingContext/*" + run: ./build/ut/clickhouse-cpp-ut.exe ${GTEST_FILTER} - - name: Test (simple) - run: ./build/tests/simple/simple-test.exe + - name: Test (simple) + run: ./build/tests/simple/simple-test.exe diff --git a/.github/workflows/windows_msvc.yml b/.github/workflows/windows_msvc.yml index 760f5ab2..47fb6764 100644 --- a/.github/workflows/windows_msvc.yml +++ b/.github/workflows/windows_msvc.yml @@ -8,6 +8,11 @@ on: pull_request: branches: [ master ] + release: + types: + - published + - prereleased + env: BUILD_TYPE: Release CLICKHOUSE_USER: clickhouse_cpp_cicd @@ -36,31 +41,34 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v2 - - uses: ilammy/msvc-dev-cmd@v1 + - uses: actions/checkout@v4 + with: + fetch-depth: 100 + fetch-tags: true + - uses: ilammy/msvc-dev-cmd@v1 - - name: Configure CMake - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBUILD_TESTS=ON + - name: Configure CMake + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBUILD_TESTS=ON - - name: Build - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + - name: Build + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} - - name: Start tls offoader proxy - shell: bash - # that mimics non-secure clickhouse running on localhost - # by tunneling queries to remote tls server - # (needed because we can't start real clickhouse instance on windows) - run: | - choco install wget - wget https://github.com/filimonov/go-tlsoffloader/releases/download/v0.1.2/go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz - tar -xvzf go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz - ./go-tlsoffloader.exe -l localhost:9000 -b github.demo.trial.altinity.cloud:9440 & + - name: Start tls offoader proxy + shell: bash + # that mimics non-secure clickhouse running on localhost + # by tunneling queries to remote tls server + # (needed because we can't start real clickhouse instance on windows) + run: | + choco install wget + wget https://github.com/filimonov/go-tlsoffloader/releases/download/v0.1.2/go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz + tar -xvzf go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz + ./go-tlsoffloader.exe -l localhost:9000 -b github.demo.trial.altinity.cloud:9440 & - - name: Test - env: - # It is impossible to start CH server in docker on Windows due to github actions limitations, - # so we use remote server to execute tests, some do not allow some features for anonymoust/free users: - # - system.query_log used by 'Client/ClientCase.Query_ID' - GTEST_FILTER: "-Client/ClientCase.Query_ID*:Client/ClientCase.TracingContext/*" - working-directory: ${{github.workspace}}/build/ut - run: Release\clickhouse-cpp-ut.exe "${{env.GTEST_FILTER}}" + - name: Test + env: + # It is impossible to start CH server in docker on Windows due to github actions limitations, + # so we use remote server to execute tests, some do not allow some features for anonymoust/free users: + # - system.query_log used by 'Client/ClientCase.Query_ID' + GTEST_FILTER: "-Client/ClientCase.Query_ID*:Client/ClientCase.TracingContext/*" + working-directory: ${{github.workspace}}/build/ut + run: Release\clickhouse-cpp-ut.exe "${{env.GTEST_FILTER}}" diff --git a/CMakeLists.txt b/CMakeLists.txt index 3152b552..77c1decf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,11 @@ -CMAKE_MINIMUM_REQUIRED (VERSION 3.0.2) +CMAKE_MINIMUM_REQUIRED (VERSION 3.5.2) LIST (APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") INCLUDE (cpp17) INCLUDE (subdirs) INCLUDE (openssl) +INCLUDE (version) OPTION (BUILD_BENCHMARK "Build benchmark" OFF) OPTION (BUILD_TESTS "Build tests" OFF) @@ -14,122 +15,130 @@ OPTION (WITH_SYSTEM_ABSEIL "Use system ABSEIL" OFF) OPTION (WITH_SYSTEM_LZ4 "Use system LZ4" OFF) OPTION (WITH_SYSTEM_CITYHASH "Use system cityhash" OFF) OPTION (DEBUG_DEPENDENCIES "Print debug info about dependencies duting build" ON) +OPTION (CHECK_VERSION "Check that version number corresponds to git tag, usefull in CI/CD to validate that new version published on GitHub has same version in sources" OFF) -PROJECT (CLICKHOUSE-CLIENT) +PROJECT (CLICKHOUSE-CLIENT + VERSION "${CLICKHOUSE_CPP_VERSION}" + DESCRIPTION "ClickHouse C++ client library" +) - USE_CXX17 () - USE_OPENSSL () +USE_CXX17 () +USE_OPENSSL () - IF (NOT CMAKE_BUILD_TYPE) - SET (CMAKE_BUILD_TYPE "RelWithDebInfo") - ENDIF () - - IF (UNIX) - IF (NOT APPLE) - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") - ENDIF () - SET (CMAKE_EXE_LINKER_FLAGS, "${CMAKE_EXE_LINKER_FLAGS} -lpthread") - # -Wpedantic makes int128 support somewhat harder and less performant (by not allowing builtin __int128) - # -Wno-deprecated-declarations to produce less cluttered output when building library itself (`deprecated` attributes are for library users) - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -Wno-deprecated-declarations") - ENDIF () - - IF (APPLE OR MSVC) - IF(BUILD_SHARED_LIBS) - MESSAGE(FATAL "Does not support shared on this platform") - ENDIF() - ENDIF() - - IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - INCLUDE (CheckCXXSourceCompiles) - - CHECK_CXX_SOURCE_COMPILES("#include \nint main() { return __GLIBCXX__ != 0; }" - CLANG_WITH_LIB_STDCXX) - ENDIF () - - IF (CLANG_WITH_LIB_STDCXX) - # there is a problem with __builtin_mul_overflow call at link time - # the error looks like: ... undefined reference to `__muloti4' ... - # caused by clang bug https://bugs.llvm.org/show_bug.cgi?id=16404 - # explicit linking to compiler-rt allows to workaround the problem - SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --rtlib=compiler-rt") - SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --rtlib=compiler-rt") - - # some workaround for linking issues on linux: - # /usr/bin/ld: CMakeFiles/simple-test.dir/main.cpp.o: undefined reference to symbol '_Unwind_Resume@@GCC_3.0' - # /usr/bin/ld: /lib/x86_64-linux-gnu/libgcc_s.so.1: error adding symbols: DSO missing from command line - # FIXME: that workaround breaks clang build on mingw - SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lgcc_s") - SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcc_s") - ENDIF () +IF (CHECK_VERSION) + clickhouse_cpp_check_library_version(FATAL_ERROR) +ENDIF () - IF (WITH_SYSTEM_ABSEIL) - FIND_PACKAGE(absl REQUIRED) - ELSE () - INCLUDE_DIRECTORIES (contrib/absl) - SUBDIRS (contrib/absl/absl) - ENDIF () +IF (NOT CMAKE_BUILD_TYPE) + SET (CMAKE_BUILD_TYPE "RelWithDebInfo") +ENDIF () - IF (WITH_SYSTEM_LZ4) - FIND_PACKAGE(lz4 REQUIRED) - ELSE () - INCLUDE_DIRECTORIES (contrib/lz4/lz4) - SUBDIRS (contrib/lz4/lz4) +IF (UNIX) + IF (NOT APPLE) + SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") ENDIF () - - IF (WITH_SYSTEM_CITYHASH) - FIND_PACKAGE(cityhash REQUIRED) - ELSE () - INCLUDE_DIRECTORIES (contrib/cityhash/cityhash) - SUBDIRS (contrib/cityhash/cityhash) - ENDIF () - + SET (CMAKE_EXE_LINKER_FLAGS, "${CMAKE_EXE_LINKER_FLAGS} -lpthread") + # -Wpedantic makes int128 support somewhat harder and less performant (by not allowing builtin __int128) + # -Wno-deprecated-declarations to produce less cluttered output when building library itself (`deprecated` attributes are for library users) + SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -Wno-deprecated-declarations") +ENDIF () + +IF (APPLE OR MSVC) + IF(BUILD_SHARED_LIBS) + MESSAGE(FATAL "Does not support shared on this platform") + ENDIF() +ENDIF() + +IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + INCLUDE (CheckCXXSourceCompiles) + + CHECK_CXX_SOURCE_COMPILES("#include \nint main() { return __GLIBCXX__ != 0; }" + CLANG_WITH_LIB_STDCXX) +ENDIF () + +IF (CLANG_WITH_LIB_STDCXX) + # there is a problem with __builtin_mul_overflow call at link time + # the error looks like: ... undefined reference to `__muloti4' ... + # caused by clang bug https://bugs.llvm.org/show_bug.cgi?id=16404 + # explicit linking to compiler-rt allows to workaround the problem + SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --rtlib=compiler-rt") + SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --rtlib=compiler-rt") + + # some workaround for linking issues on linux: + # /usr/bin/ld: CMakeFiles/simple-test.dir/main.cpp.o: undefined reference to symbol '_Unwind_Resume@@GCC_3.0' + # /usr/bin/ld: /lib/x86_64-linux-gnu/libgcc_s.so.1: error adding symbols: DSO missing from command line + # FIXME: that workaround breaks clang build on mingw + SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lgcc_s") + SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcc_s") +ENDIF () + +IF (WITH_SYSTEM_ABSEIL) + FIND_PACKAGE(absl REQUIRED) +ELSE () + INCLUDE_DIRECTORIES (contrib/absl) + SUBDIRS (contrib/absl/absl) +ENDIF () + +IF (WITH_SYSTEM_LZ4) + FIND_PACKAGE(lz4 REQUIRED) +ELSE () + INCLUDE_DIRECTORIES (contrib/lz4/lz4) + SUBDIRS (contrib/lz4/lz4) +ENDIF () + +IF (WITH_SYSTEM_CITYHASH) + FIND_PACKAGE(cityhash REQUIRED) +ELSE () + INCLUDE_DIRECTORIES (contrib/cityhash/cityhash) + SUBDIRS (contrib/cityhash/cityhash) +ENDIF () + +SUBDIRS ( + clickhouse +) + +IF (BUILD_BENCHMARK) + SUBDIRS (bench) +ENDIF (BUILD_BENCHMARK) + +IF (BUILD_TESTS) + INCLUDE_DIRECTORIES (contrib/gtest/include contrib/gtest) SUBDIRS ( - clickhouse + contrib/gtest + tests/simple + ut ) - - IF (BUILD_BENCHMARK) - SUBDIRS (bench) - ENDIF (BUILD_BENCHMARK) - - IF (BUILD_TESTS) - INCLUDE_DIRECTORIES (contrib/gtest/include contrib/gtest) - SUBDIRS ( - contrib/gtest - tests/simple - ut +ENDIF (BUILD_TESTS) + +if(DEBUG_DEPENDENCIES) + function(print_target_properties target) + MESSAGE("${target} properties:") + set(properties "${ARGN}") + foreach(property_name ${properties}) + get_target_property(PROPERTY ${target} ${property_name}) + MESSAGE(NOTICE "\t${property_name} : ${PROPERTY}") + endforeach() + + # Can't get path to the target file at configure time, + # so have to create a target to fetch that info at generate time. + string(REPLACE ":" "_" target_plain_name ${target}) + add_custom_target(${target_plain_name}_print_debug_info COMMAND ${CMAKE_COMMAND} -E echo "${target} : $") + add_dependencies(clickhouse-cpp-lib ${target_plain_name}_print_debug_info) + endfunction() + + function(print_target_debug_info target) + print_target_properties(${target} + INCLUDE_DIRECTORIES + BINARY_DIR + INTERFACE_INCLUDE_DIRECTORIES + INTERFACE_LINK_LIBRARIES + LINK_LIBRARIES + LINK_LIBRARIES_ONLY_TARGETS + IMPORTED_LOCATION ) - ENDIF (BUILD_TESTS) - - if(DEBUG_DEPENDENCIES) - function(print_target_properties target) - MESSAGE("${target} properties:") - set(properties "${ARGN}") - foreach(property_name ${properties}) - get_target_property(PROPERTY ${target} ${property_name}) - MESSAGE(NOTICE "\t${property_name} : ${PROPERTY}") - endforeach() - - # Can't get path to the target file at configure time, - # so have to create a target to fetch that info at generate time. - string(REPLACE ":" "_" target_plain_name ${target}) - add_custom_target(${target_plain_name}_print_debug_info COMMAND ${CMAKE_COMMAND} -E echo "${target} : $") - add_dependencies(clickhouse-cpp-lib ${target_plain_name}_print_debug_info) - endfunction() - - function(print_target_debug_info target) - print_target_properties(${target} - INCLUDE_DIRECTORIES - BINARY_DIR - INTERFACE_INCLUDE_DIRECTORIES - INTERFACE_LINK_LIBRARIES - LINK_LIBRARIES - LINK_LIBRARIES_ONLY_TARGETS - IMPORTED_LOCATION - ) - endfunction() - - print_target_debug_info(absl::int128) - print_target_debug_info(cityhash::cityhash) - print_target_debug_info(lz4::lz4) - endif() + endfunction() + + print_target_debug_info(absl::int128) + print_target_debug_info(cityhash::cityhash) + print_target_debug_info(lz4::lz4) +endif() diff --git a/clickhouse/CMakeLists.txt b/clickhouse/CMakeLists.txt index 97f8cc56..1919418a 100644 --- a/clickhouse/CMakeLists.txt +++ b/clickhouse/CMakeLists.txt @@ -102,8 +102,13 @@ IF (WITH_OPENSSL) LIST(APPEND clickhouse-cpp-lib-src base/sslsocket.cpp) ENDIF () -ADD_LIBRARY (clickhouse-cpp-lib ${clickhouse-cpp-lib-src}) -SET_TARGET_PROPERTIES (clickhouse-cpp-lib PROPERTIES LINKER_LANGUAGE CXX) +ADD_LIBRARY (clickhouse-cpp-lib ${clickhouse-cpp-lib-src} + version.h) +SET_TARGET_PROPERTIES (clickhouse-cpp-lib + PROPERTIES + LINKER_LANGUAGE CXX + VERSION ${CLICKHOUSE_CPP_VERSION} +) TARGET_LINK_LIBRARIES (clickhouse-cpp-lib absl::int128 cityhash::cityhash @@ -115,7 +120,13 @@ TARGET_INCLUDE_DIRECTORIES (clickhouse-cpp-lib IF (NOT BUILD_SHARED_LIBS) ADD_LIBRARY (clickhouse-cpp-lib-static ALIAS clickhouse-cpp-lib) -ENDIF() +ELSE () + SET_TARGET_PROPERTIES (clickhouse-cpp-lib + PROPERTIES + SO_VERSION ${CLICKHOUSE_CPP_VERSION} + SO_VERSION ${CLICKHOUSE_CPP_VERSION_MAJOR} + ) +ENDIF () IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") @@ -153,6 +164,7 @@ INSTALL(FILES exceptions.h DESTINATION include/clickhouse/) INSTALL(FILES server_exception.h DESTINATION include/clickhouse/) INSTALL(FILES protocol.h DESTINATION include/clickhouse/) INSTALL(FILES query.h DESTINATION include/clickhouse/) +INSTALL(FILES version.h DESTINATION include/clickhouse/) # base INSTALL(FILES base/buffer.h DESTINATION include/clickhouse/base/) diff --git a/clickhouse/base/compressed.cpp b/clickhouse/base/compressed.cpp index 135f9483..b5cefe4c 100644 --- a/clickhouse/base/compressed.cpp +++ b/clickhouse/base/compressed.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include diff --git a/clickhouse/client.cpp b/clickhouse/client.cpp index 6f7ea213..25810274 100644 --- a/clickhouse/client.cpp +++ b/clickhouse/client.cpp @@ -1,4 +1,5 @@ #include "client.h" +#include "clickhouse/version.h" #include "protocol.h" #include "base/compressed.h" @@ -8,20 +9,15 @@ #include "columns/factory.h" #include -#include #include -#include #include #include -#include #if defined(WITH_OPENSSL) #include "base/sslsocket.h" #endif #define DBMS_NAME "ClickHouse" -#define DBMS_VERSION_MAJOR 2 -#define DBMS_VERSION_MINOR 1 #define DBMS_MIN_REVISION_WITH_TEMPORARY_TABLES 50264 #define DBMS_MIN_REVISION_WITH_TOTAL_ROWS_IN_PROGRESS 51554 @@ -43,7 +39,7 @@ #define DBMS_MIN_REVISION_WITH_INITIAL_QUERY_START_TIME 54449 #define DBMS_MIN_REVISION_WITH_INCREMENTAL_PROFILE_EVENTS 54451 -#define REVISION DBMS_MIN_REVISION_WITH_INCREMENTAL_PROFILE_EVENTS +#define DMBS_PROTOCOL_REVISION DBMS_MIN_REVISION_WITH_INCREMENTAL_PROFILE_EVENTS namespace clickhouse { @@ -63,14 +59,30 @@ struct ClientInfo { uint32_t client_revision = 0; }; +std::ostream& operator<<(std::ostream& os, const Endpoint& endpoint) { + return os << endpoint.host << ":" << endpoint.port; +} + std::ostream& operator<<(std::ostream& os, const ClientOptions& opt) { - os << "Client(" << opt.user << '@' << opt.host << ":" << opt.port - << "Endpoints :"; - for (size_t i = 0; i < opt.endpoints.size(); i++) - os << opt.user << '@' << opt.endpoints[i].host << ":" << opt.endpoints[i].port + os << "Client(" + << " Endpoints : ["; + size_t extra_endpoints = 0; + + if (!opt.host.empty()) { + extra_endpoints = 1; + os << opt.user << '@' << Endpoint{opt.host, opt.port}; + + if (opt.endpoints.size()) + os << ", "; + } + + for (size_t i = 0; i < opt.endpoints.size(); i++) { + os << opt.user << '@' << opt.endpoints[i] << ((i == opt.endpoints.size() - 1) ? "" : ", "); + } - os << " ping_before_query:" << opt.ping_before_query + os << "] (" << opt.endpoints.size() + extra_endpoints << " items )" + << " ping_before_query:" << opt.ping_before_query << " send_retries:" << opt.send_retries << " retry_timeout:" << opt.retry_timeout.count() << " compression_method:" @@ -483,12 +495,12 @@ bool Client::Impl::ReceivePacket(uint64_t* server_packet) { if (!WireFormat::ReadUInt64(*input_, &info.bytes)) { return false; } - if constexpr(REVISION >= DBMS_MIN_REVISION_WITH_TOTAL_ROWS_IN_PROGRESS) { + if constexpr(DMBS_PROTOCOL_REVISION >= DBMS_MIN_REVISION_WITH_TOTAL_ROWS_IN_PROGRESS) { if (!WireFormat::ReadUInt64(*input_, &info.total_rows)) { return false; } } - if constexpr (REVISION >= DBMS_MIN_REVISION_WITH_CLIENT_WRITE_INFO) + if constexpr (DMBS_PROTOCOL_REVISION >= DBMS_MIN_REVISION_WITH_CLIENT_WRITE_INFO) { if (!WireFormat::ReadUInt64(*input_, &info.written_rows)) { return false; @@ -575,7 +587,7 @@ bool Client::Impl::ReceivePacket(uint64_t* server_packet) { bool Client::Impl::ReadBlock(InputStream& input, Block* block) { // Additional information about block. - if constexpr (REVISION >= DBMS_MIN_REVISION_WITH_BLOCK_INFO) { + if constexpr (DMBS_PROTOCOL_REVISION >= DBMS_MIN_REVISION_WITH_BLOCK_INFO) { uint64_t num; BlockInfo info; @@ -639,7 +651,7 @@ bool Client::Impl::ReadBlock(InputStream& input, Block* block) { bool Client::Impl::ReceiveData() { Block block; - if constexpr (REVISION >= DBMS_MIN_REVISION_WITH_TEMPORARY_TABLES) { + if constexpr (DMBS_PROTOCOL_REVISION >= DBMS_MIN_REVISION_WITH_TEMPORARY_TABLES) { if (!WireFormat::SkipString(*input_)) { return false; } @@ -729,9 +741,10 @@ void Client::Impl::SendQuery(const Query& query) { info.query_kind = 1; info.client_name = "ClickHouse client"; - info.client_version_major = DBMS_VERSION_MAJOR; - info.client_version_minor = DBMS_VERSION_MINOR; - info.client_revision = REVISION; + info.client_version_major = CLICKHOUSE_CPP_VERSION_MAJOR; + info.client_version_minor = CLICKHOUSE_CPP_VERSION_MINOR; + info.client_version_patch = CLICKHOUSE_CPP_VERSION_PATCH; + info.client_revision = DMBS_PROTOCOL_REVISION; WireFormat::WriteFixed(*output_, info.query_kind); @@ -870,9 +883,9 @@ void Client::Impl::InitializeStreams(std::unique_ptr&& socket) { bool Client::Impl::SendHello() { WireFormat::WriteUInt64(*output_, ClientCodes::Hello); WireFormat::WriteString(*output_, std::string(DBMS_NAME) + " client"); - WireFormat::WriteUInt64(*output_, DBMS_VERSION_MAJOR); - WireFormat::WriteUInt64(*output_, DBMS_VERSION_MINOR); - WireFormat::WriteUInt64(*output_, REVISION); + WireFormat::WriteUInt64(*output_, CLICKHOUSE_CPP_VERSION_MAJOR); + WireFormat::WriteUInt64(*output_, CLICKHOUSE_CPP_VERSION_MINOR); + WireFormat::WriteUInt64(*output_, DMBS_PROTOCOL_REVISION); WireFormat::WriteString(*output_, options_.default_database); WireFormat::WriteString(*output_, options_.user); WireFormat::WriteString(*output_, options_.password); @@ -1044,4 +1057,14 @@ const ServerInfo& Client::GetServerInfo() const { return impl_->GetServerInfo(); } +Client::Version Client::GetVersion() { + return Version { + CLICKHOUSE_CPP_VERSION_MAJOR, + CLICKHOUSE_CPP_VERSION_MINOR, + CLICKHOUSE_CPP_VERSION_PATCH, + CLICKHOUSE_CPP_VERSION_BUILD, + "" + }; +} + } diff --git a/clickhouse/client.h b/clickhouse/client.h index 35000784..9cca09fe 100644 --- a/clickhouse/client.h +++ b/clickhouse/client.h @@ -19,6 +19,7 @@ #include "columns/uuid.h" #include +#include #include #include #include @@ -219,6 +220,7 @@ struct ClientOptions { }; std::ostream& operator<<(std::ostream& os, const ClientOptions& options); +std::ostream& operator<<(std::ostream& os, const Endpoint& options); class SocketFactory; @@ -266,6 +268,18 @@ class Client { // Try to connect to different endpoints one by one only one time. If it doesn't work, throw an exception. void ResetConnectionEndpoint(); + + struct Version + { + uint16_t major; + uint16_t minor; + uint16_t patch; + uint16_t build; + const char * extra; + }; + + static Version GetVersion(); + private: const ClientOptions options_; diff --git a/clickhouse/columns/array.h b/clickhouse/columns/array.h index 0491dc65..83bacff0 100644 --- a/clickhouse/columns/array.h +++ b/clickhouse/columns/array.h @@ -262,8 +262,16 @@ class ColumnArrayT : public ColumnArray { using ColumnArray::Append; template - inline void Append(const Container& container) { - Append(std::begin(container), std::end(container)); + inline void Append(Container&& container) { + using container_type = decltype(container); + if constexpr (std::is_lvalue_reference_v || + std::is_const_v>) { + Append(std::begin(container), std::end(container)); + } + else { + Append(std::make_move_iterator(std::begin(container)), + std::make_move_iterator(std::end(container))); + } } template @@ -272,12 +280,12 @@ class ColumnArrayT : public ColumnArray { } template - inline void Append(Begin begin, const End & end) { + inline void Append(Begin begin, End end) { auto & nested_data = *typed_nested_data_; size_t counter = 0; while (begin != end) { - nested_data.Append(std::move(*begin)); + nested_data.Append(*begin); ++begin; ++counter; } diff --git a/clickhouse/columns/string.cpp b/clickhouse/columns/string.cpp index f0d34aed..8ea60bfc 100644 --- a/clickhouse/columns/string.cpp +++ b/clickhouse/columns/string.cpp @@ -308,7 +308,6 @@ void ColumnString::Clear() { items_.clear(); blocks_.clear(); append_data_.clear(); - append_data_.shrink_to_fit(); } std::string_view ColumnString::At(size_t n) const { diff --git a/clickhouse/error_codes.h b/clickhouse/error_codes.h index 77e88ee0..815a984f 100644 --- a/clickhouse/error_codes.h +++ b/clickhouse/error_codes.h @@ -2,27 +2,593 @@ namespace clickhouse { +// based on https://github.com/ClickHouse/ClickHouse/blob/54ae88a859507722821624476c3818152f944055/src/Common/ErrorCodes.cpp +// (master on 28 Feb 2024) enum ErrorCodes { + OK = 0, + UNSUPPORTED_METHOD = 1, + UNSUPPORTED_PARAMETER = 2, + UNEXPECTED_END_OF_FILE = 3, + EXPECTED_END_OF_FILE = 4, + CANNOT_PARSE_TEXT = 6, + INCORRECT_NUMBER_OF_COLUMNS = 7, + THERE_IS_NO_COLUMN = 8, + SIZES_OF_COLUMNS_DOESNT_MATCH = 9, + NOT_FOUND_COLUMN_IN_BLOCK = 10, + POSITION_OUT_OF_BOUND = 11, + PARAMETER_OUT_OF_BOUND = 12, + SIZES_OF_COLUMNS_IN_TUPLE_DOESNT_MATCH = 13, + DUPLICATE_COLUMN = 15, + NO_SUCH_COLUMN_IN_TABLE = 16, + SIZE_OF_FIXED_STRING_DOESNT_MATCH = 19, + NUMBER_OF_COLUMNS_DOESNT_MATCH = 20, + CANNOT_READ_FROM_ISTREAM = 23, + CANNOT_WRITE_TO_OSTREAM = 24, + CANNOT_PARSE_ESCAPE_SEQUENCE = 25, + CANNOT_PARSE_QUOTED_STRING = 26, + CANNOT_PARSE_INPUT_ASSERTION_FAILED = 27, + CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER = 28, + ATTEMPT_TO_READ_AFTER_EOF = 32, + CANNOT_READ_ALL_DATA = 33, + TOO_MANY_ARGUMENTS_FOR_FUNCTION = 34, + TOO_FEW_ARGUMENTS_FOR_FUNCTION = 35, + BAD_ARGUMENTS = 36, + UNKNOWN_ELEMENT_IN_AST = 37, + CANNOT_PARSE_DATE = 38, + TOO_LARGE_SIZE_COMPRESSED = 39, CHECKSUM_DOESNT_MATCH = 40, CANNOT_PARSE_DATETIME = 41, + NUMBER_OF_ARGUMENTS_DOESNT_MATCH = 42, + ILLEGAL_TYPE_OF_ARGUMENT = 43, + ILLEGAL_COLUMN = 44, UNKNOWN_FUNCTION = 46, UNKNOWN_IDENTIFIER = 47, + NOT_IMPLEMENTED = 48, + LOGICAL_ERROR = 49, + UNKNOWN_TYPE = 50, + EMPTY_LIST_OF_COLUMNS_QUERIED = 51, + COLUMN_QUERIED_MORE_THAN_ONCE = 52, + TYPE_MISMATCH = 53, + STORAGE_REQUIRES_PARAMETER = 55, + UNKNOWN_STORAGE = 56, TABLE_ALREADY_EXISTS = 57, + TABLE_METADATA_ALREADY_EXISTS = 58, + ILLEGAL_TYPE_OF_COLUMN_FOR_FILTER = 59, UNKNOWN_TABLE = 60, SYNTAX_ERROR = 62, + UNKNOWN_AGGREGATE_FUNCTION = 63, + CANNOT_GET_SIZE_OF_FIELD = 68, + ARGUMENT_OUT_OF_BOUND = 69, + CANNOT_CONVERT_TYPE = 70, + CANNOT_WRITE_AFTER_END_OF_BUFFER = 71, + CANNOT_PARSE_NUMBER = 72, + UNKNOWN_FORMAT = 73, + CANNOT_READ_FROM_FILE_DESCRIPTOR = 74, + CANNOT_WRITE_TO_FILE_DESCRIPTOR = 75, + CANNOT_OPEN_FILE = 76, + CANNOT_CLOSE_FILE = 77, + UNKNOWN_TYPE_OF_QUERY = 78, + INCORRECT_FILE_NAME = 79, + INCORRECT_QUERY = 80, UNKNOWN_DATABASE = 81, DATABASE_ALREADY_EXISTS = 82, + DIRECTORY_DOESNT_EXIST = 83, + DIRECTORY_ALREADY_EXISTS = 84, + FORMAT_IS_NOT_SUITABLE_FOR_INPUT = 85, + RECEIVED_ERROR_FROM_REMOTE_IO_SERVER = 86, + CANNOT_SEEK_THROUGH_FILE = 87, + CANNOT_TRUNCATE_FILE = 88, + UNKNOWN_COMPRESSION_METHOD = 89, + EMPTY_LIST_OF_COLUMNS_PASSED = 90, + SIZES_OF_MARKS_FILES_ARE_INCONSISTENT = 91, + EMPTY_DATA_PASSED = 92, + UNKNOWN_AGGREGATED_DATA_VARIANT = 93, + CANNOT_MERGE_DIFFERENT_AGGREGATED_DATA_VARIANTS = 94, + CANNOT_READ_FROM_SOCKET = 95, + CANNOT_WRITE_TO_SOCKET = 96, UNKNOWN_PACKET_FROM_CLIENT = 99, + UNKNOWN_PACKET_FROM_SERVER = 100, UNEXPECTED_PACKET_FROM_CLIENT = 101, - RECEIVED_DATA_FOR_WRONG_QUERY_ID = 103, + UNEXPECTED_PACKET_FROM_SERVER = 102, + TOO_SMALL_BUFFER_SIZE = 104, + FILE_DOESNT_EXIST = 107, + NO_DATA_TO_INSERT = 108, + CANNOT_BLOCK_SIGNAL = 109, + CANNOT_UNBLOCK_SIGNAL = 110, + CANNOT_MANIPULATE_SIGSET = 111, + CANNOT_WAIT_FOR_SIGNAL = 112, + THERE_IS_NO_SESSION = 113, + CANNOT_CLOCK_GETTIME = 114, + UNKNOWN_SETTING = 115, + THERE_IS_NO_DEFAULT_VALUE = 116, + INCORRECT_DATA = 117, ENGINE_REQUIRED = 119, + CANNOT_INSERT_VALUE_OF_DIFFERENT_SIZE_INTO_TUPLE = 120, + UNSUPPORTED_JOIN_KEYS = 121, + INCOMPATIBLE_COLUMNS = 122, + UNKNOWN_TYPE_OF_AST_NODE = 123, + INCORRECT_ELEMENT_OF_SET = 124, + INCORRECT_RESULT_OF_SCALAR_SUBQUERY = 125, + ILLEGAL_INDEX = 127, + TOO_LARGE_ARRAY_SIZE = 128, + FUNCTION_IS_SPECIAL = 129, + CANNOT_READ_ARRAY_FROM_TEXT = 130, + TOO_LARGE_STRING_SIZE = 131, + AGGREGATE_FUNCTION_DOESNT_ALLOW_PARAMETERS = 133, + PARAMETERS_TO_AGGREGATE_FUNCTIONS_MUST_BE_LITERALS = 134, + ZERO_ARRAY_OR_TUPLE_INDEX = 135, + UNKNOWN_ELEMENT_IN_CONFIG = 137, + EXCESSIVE_ELEMENT_IN_CONFIG = 138, + NO_ELEMENTS_IN_CONFIG = 139, + SAMPLING_NOT_SUPPORTED = 141, + NOT_FOUND_NODE = 142, + UNKNOWN_OVERFLOW_MODE = 145, + UNKNOWN_DIRECTION_OF_SORTING = 152, + ILLEGAL_DIVISION = 153, + DICTIONARIES_WAS_NOT_LOADED = 156, + TOO_MANY_ROWS = 158, + TIMEOUT_EXCEEDED = 159, + TOO_SLOW = 160, + TOO_MANY_COLUMNS = 161, + TOO_DEEP_SUBQUERIES = 162, READONLY = 164, + TOO_MANY_TEMPORARY_COLUMNS = 165, + TOO_MANY_TEMPORARY_NON_CONST_COLUMNS = 166, + TOO_DEEP_AST = 167, + TOO_BIG_AST = 168, + BAD_TYPE_OF_FIELD = 169, + BAD_GET = 170, + CANNOT_CREATE_DIRECTORY = 172, + CANNOT_ALLOCATE_MEMORY = 173, + CYCLIC_ALIASES = 174, + MULTIPLE_EXPRESSIONS_FOR_ALIAS = 179, + THERE_IS_NO_PROFILE = 180, + ILLEGAL_FINAL = 181, + ILLEGAL_PREWHERE = 182, + UNEXPECTED_EXPRESSION = 183, + ILLEGAL_AGGREGATION = 184, + UNSUPPORTED_COLLATION_LOCALE = 186, + COLLATION_COMPARISON_FAILED = 187, + SIZES_OF_ARRAYS_DONT_MATCH = 190, + SET_SIZE_LIMIT_EXCEEDED = 191, UNKNOWN_USER = 192, WRONG_PASSWORD = 193, REQUIRED_PASSWORD = 194, IP_ADDRESS_NOT_ALLOWED = 195, + UNKNOWN_ADDRESS_PATTERN_TYPE = 196, + DNS_ERROR = 198, + UNKNOWN_QUOTA = 199, + QUOTA_EXCEEDED = 201, + TOO_MANY_SIMULTANEOUS_QUERIES = 202, + NO_FREE_CONNECTION = 203, + CANNOT_FSYNC = 204, + ALIAS_REQUIRED = 206, + AMBIGUOUS_IDENTIFIER = 207, + EMPTY_NESTED_TABLE = 208, + SOCKET_TIMEOUT = 209, + NETWORK_ERROR = 210, + EMPTY_QUERY = 211, + UNKNOWN_LOAD_BALANCING = 212, + UNKNOWN_TOTALS_MODE = 213, + CANNOT_STATVFS = 214, + NOT_AN_AGGREGATE = 215, + QUERY_WITH_SAME_ID_IS_ALREADY_RUNNING = 216, + CLIENT_HAS_CONNECTED_TO_WRONG_PORT = 217, + TABLE_IS_DROPPED = 218, + DATABASE_NOT_EMPTY = 219, + DUPLICATE_INTERSERVER_IO_ENDPOINT = 220, + NO_SUCH_INTERSERVER_IO_ENDPOINT = 221, + UNEXPECTED_AST_STRUCTURE = 223, + REPLICA_IS_ALREADY_ACTIVE = 224, + NO_ZOOKEEPER = 225, + NO_FILE_IN_DATA_PART = 226, + UNEXPECTED_FILE_IN_DATA_PART = 227, + BAD_SIZE_OF_FILE_IN_DATA_PART = 228, + QUERY_IS_TOO_LARGE = 229, + NOT_FOUND_EXPECTED_DATA_PART = 230, + TOO_MANY_UNEXPECTED_DATA_PARTS = 231, + NO_SUCH_DATA_PART = 232, + BAD_DATA_PART_NAME = 233, + NO_REPLICA_HAS_PART = 234, + DUPLICATE_DATA_PART = 235, + ABORTED = 236, + NO_REPLICA_NAME_GIVEN = 237, + FORMAT_VERSION_TOO_OLD = 238, + CANNOT_MUNMAP = 239, + CANNOT_MREMAP = 240, + MEMORY_LIMIT_EXCEEDED = 241, + TABLE_IS_READ_ONLY = 242, + NOT_ENOUGH_SPACE = 243, + UNEXPECTED_ZOOKEEPER_ERROR = 244, + CORRUPTED_DATA = 246, + INVALID_PARTITION_VALUE = 248, + NO_SUCH_REPLICA = 251, + TOO_MANY_PARTS = 252, + REPLICA_ALREADY_EXISTS = 253, + NO_ACTIVE_REPLICAS = 254, + TOO_MANY_RETRIES_TO_FETCH_PARTS = 255, + PARTITION_ALREADY_EXISTS = 256, + PARTITION_DOESNT_EXIST = 257, + UNION_ALL_RESULT_STRUCTURES_MISMATCH = 258, + CLIENT_OUTPUT_FORMAT_SPECIFIED = 260, + UNKNOWN_BLOCK_INFO_FIELD = 261, + BAD_COLLATION = 262, + CANNOT_COMPILE_CODE = 263, + INCOMPATIBLE_TYPE_OF_JOIN = 264, + NO_AVAILABLE_REPLICA = 265, + MISMATCH_REPLICAS_DATA_SOURCES = 266, + INFINITE_LOOP = 269, + CANNOT_COMPRESS = 270, + CANNOT_DECOMPRESS = 271, + CANNOT_IO_SUBMIT = 272, + CANNOT_IO_GETEVENTS = 273, + AIO_READ_ERROR = 274, + AIO_WRITE_ERROR = 275, + INDEX_NOT_USED = 277, + ALL_CONNECTION_TRIES_FAILED = 279, + NO_AVAILABLE_DATA = 280, + DICTIONARY_IS_EMPTY = 281, + INCORRECT_INDEX = 282, + UNKNOWN_DISTRIBUTED_PRODUCT_MODE = 283, + WRONG_GLOBAL_SUBQUERY = 284, + TOO_FEW_LIVE_REPLICAS = 285, + UNSATISFIED_QUORUM_FOR_PREVIOUS_WRITE = 286, + UNKNOWN_FORMAT_VERSION = 287, + DISTRIBUTED_IN_JOIN_SUBQUERY_DENIED = 288, + REPLICA_IS_NOT_IN_QUORUM = 289, LIMIT_EXCEEDED = 290, + DATABASE_ACCESS_DENIED = 291, + MONGODB_CANNOT_AUTHENTICATE = 293, + RECEIVED_EMPTY_DATA = 295, + SHARD_HAS_NO_CONNECTIONS = 297, + CANNOT_PIPE = 298, + CANNOT_FORK = 299, + CANNOT_DLSYM = 300, + CANNOT_CREATE_CHILD_PROCESS = 301, + CHILD_WAS_NOT_EXITED_NORMALLY = 302, + CANNOT_SELECT = 303, + CANNOT_WAITPID = 304, + TABLE_WAS_NOT_DROPPED = 305, + TOO_DEEP_RECURSION = 306, + TOO_MANY_BYTES = 307, + UNEXPECTED_NODE_IN_ZOOKEEPER = 308, + FUNCTION_CANNOT_HAVE_PARAMETERS = 309, + INVALID_CONFIG_PARAMETER = 318, + UNKNOWN_STATUS_OF_INSERT = 319, + VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE = 321, UNKNOWN_DATABASE_ENGINE = 336, + UNFINISHED = 341, + METADATA_MISMATCH = 342, + SUPPORT_IS_DISABLED = 344, + TABLE_DIFFERS_TOO_MUCH = 345, + CANNOT_CONVERT_CHARSET = 346, + CANNOT_LOAD_CONFIG = 347, + CANNOT_INSERT_NULL_IN_ORDINARY_COLUMN = 349, + AMBIGUOUS_COLUMN_NAME = 352, + INDEX_OF_POSITIONAL_ARGUMENT_IS_OUT_OF_RANGE = 353, + ZLIB_INFLATE_FAILED = 354, + ZLIB_DEFLATE_FAILED = 355, + INTO_OUTFILE_NOT_ALLOWED = 358, + TABLE_SIZE_EXCEEDS_MAX_DROP_SIZE_LIMIT = 359, + CANNOT_CREATE_CHARSET_CONVERTER = 360, + SEEK_POSITION_OUT_OF_BOUND = 361, + CURRENT_WRITE_BUFFER_IS_EXHAUSTED = 362, + CANNOT_CREATE_IO_BUFFER = 363, + RECEIVED_ERROR_TOO_MANY_REQUESTS = 364, + SIZES_OF_NESTED_COLUMNS_ARE_INCONSISTENT = 366, + ALL_REPLICAS_ARE_STALE = 369, + DATA_TYPE_CANNOT_BE_USED_IN_TABLES = 370, + INCONSISTENT_CLUSTER_DEFINITION = 371, + SESSION_NOT_FOUND = 372, + SESSION_IS_LOCKED = 373, + INVALID_SESSION_TIMEOUT = 374, + CANNOT_DLOPEN = 375, + CANNOT_PARSE_UUID = 376, + ILLEGAL_SYNTAX_FOR_DATA_TYPE = 377, + DATA_TYPE_CANNOT_HAVE_ARGUMENTS = 378, + CANNOT_KILL = 380, + HTTP_LENGTH_REQUIRED = 381, + CANNOT_LOAD_CATBOOST_MODEL = 382, + CANNOT_APPLY_CATBOOST_MODEL = 383, + PART_IS_TEMPORARILY_LOCKED = 384, + MULTIPLE_STREAMS_REQUIRED = 385, + NO_COMMON_TYPE = 386, + DICTIONARY_ALREADY_EXISTS = 387, + CANNOT_ASSIGN_OPTIMIZE = 388, + INSERT_WAS_DEDUPLICATED = 389, + CANNOT_GET_CREATE_TABLE_QUERY = 390, + EXTERNAL_LIBRARY_ERROR = 391, + QUERY_IS_PROHIBITED = 392, + THERE_IS_NO_QUERY = 393, + QUERY_WAS_CANCELLED = 394, + FUNCTION_THROW_IF_VALUE_IS_NON_ZERO = 395, + TOO_MANY_ROWS_OR_BYTES = 396, + QUERY_IS_NOT_SUPPORTED_IN_MATERIALIZED_VIEW = 397, + UNKNOWN_MUTATION_COMMAND = 398, + FORMAT_IS_NOT_SUITABLE_FOR_OUTPUT = 399, + CANNOT_STAT = 400, + FEATURE_IS_NOT_ENABLED_AT_BUILD_TIME = 401, + CANNOT_IOSETUP = 402, + INVALID_JOIN_ON_EXPRESSION = 403, + BAD_ODBC_CONNECTION_STRING = 404, + TOP_AND_LIMIT_TOGETHER = 406, + DECIMAL_OVERFLOW = 407, + BAD_REQUEST_PARAMETER = 408, + EXTERNAL_SERVER_IS_NOT_RESPONDING = 410, + PTHREAD_ERROR = 411, + NETLINK_ERROR = 412, + CANNOT_SET_SIGNAL_HANDLER = 413, + ALL_REPLICAS_LOST = 415, + REPLICA_STATUS_CHANGED = 416, + EXPECTED_ALL_OR_ANY = 417, + UNKNOWN_JOIN = 418, + MULTIPLE_ASSIGNMENTS_TO_COLUMN = 419, + CANNOT_UPDATE_COLUMN = 420, + CANNOT_ADD_DIFFERENT_AGGREGATE_STATES = 421, + UNSUPPORTED_URI_SCHEME = 422, + CANNOT_GETTIMEOFDAY = 423, + CANNOT_LINK = 424, + SYSTEM_ERROR = 425, + CANNOT_COMPILE_REGEXP = 427, + FAILED_TO_GETPWUID = 429, + MISMATCHING_USERS_FOR_PROCESS_AND_DATA = 430, + ILLEGAL_SYNTAX_FOR_CODEC_TYPE = 431, + UNKNOWN_CODEC = 432, + ILLEGAL_CODEC_PARAMETER = 433, + CANNOT_PARSE_PROTOBUF_SCHEMA = 434, + NO_COLUMN_SERIALIZED_TO_REQUIRED_PROTOBUF_FIELD = 435, + PROTOBUF_BAD_CAST = 436, + PROTOBUF_FIELD_NOT_REPEATED = 437, + DATA_TYPE_CANNOT_BE_PROMOTED = 438, + CANNOT_SCHEDULE_TASK = 439, + INVALID_LIMIT_EXPRESSION = 440, + CANNOT_PARSE_DOMAIN_VALUE_FROM_STRING = 441, + BAD_DATABASE_FOR_TEMPORARY_TABLE = 442, + NO_COLUMNS_SERIALIZED_TO_PROTOBUF_FIELDS = 443, + UNKNOWN_PROTOBUF_FORMAT = 444, + CANNOT_MPROTECT = 445, + FUNCTION_NOT_ALLOWED = 446, + HYPERSCAN_CANNOT_SCAN_TEXT = 447, + BROTLI_READ_FAILED = 448, + BROTLI_WRITE_FAILED = 449, + BAD_TTL_EXPRESSION = 450, + BAD_TTL_FILE = 451, + SETTING_CONSTRAINT_VIOLATION = 452, + MYSQL_CLIENT_INSUFFICIENT_CAPABILITIES = 453, + OPENSSL_ERROR = 454, + SUSPICIOUS_TYPE_FOR_LOW_CARDINALITY = 455, + UNKNOWN_QUERY_PARAMETER = 456, + BAD_QUERY_PARAMETER = 457, + CANNOT_UNLINK = 458, + CANNOT_SET_THREAD_PRIORITY = 459, + CANNOT_CREATE_TIMER = 460, + CANNOT_SET_TIMER_PERIOD = 461, + CANNOT_FCNTL = 463, + CANNOT_PARSE_ELF = 464, + CANNOT_PARSE_DWARF = 465, + INSECURE_PATH = 466, + CANNOT_PARSE_BOOL = 467, + CANNOT_PTHREAD_ATTR = 468, + VIOLATED_CONSTRAINT = 469, + QUERY_IS_NOT_SUPPORTED_IN_LIVE_VIEW = 470, + INVALID_SETTING_VALUE = 471, + READONLY_SETTING = 472, + DEADLOCK_AVOIDED = 473, + INVALID_TEMPLATE_FORMAT = 474, + INVALID_WITH_FILL_EXPRESSION = 475, + WITH_TIES_WITHOUT_ORDER_BY = 476, + INVALID_USAGE_OF_INPUT = 477, + UNKNOWN_POLICY = 478, + UNKNOWN_DISK = 479, + UNKNOWN_PROTOCOL = 480, + PATH_ACCESS_DENIED = 481, + DICTIONARY_ACCESS_DENIED = 482, + TOO_MANY_REDIRECTS = 483, + INTERNAL_REDIS_ERROR = 484, + CANNOT_GET_CREATE_DICTIONARY_QUERY = 487, + INCORRECT_DICTIONARY_DEFINITION = 489, + CANNOT_FORMAT_DATETIME = 490, + UNACCEPTABLE_URL = 491, + ACCESS_ENTITY_NOT_FOUND = 492, + ACCESS_ENTITY_ALREADY_EXISTS = 493, + ACCESS_STORAGE_READONLY = 495, + QUOTA_REQUIRES_CLIENT_KEY = 496, + ACCESS_DENIED = 497, + LIMIT_BY_WITH_TIES_IS_NOT_SUPPORTED = 498, + S3_ERROR = 499, + AZURE_BLOB_STORAGE_ERROR = 500, + CANNOT_CREATE_DATABASE = 501, + CANNOT_SIGQUEUE = 502, + AGGREGATE_FUNCTION_THROW = 503, + FILE_ALREADY_EXISTS = 504, + UNABLE_TO_SKIP_UNUSED_SHARDS = 507, + UNKNOWN_ACCESS_TYPE = 508, + INVALID_GRANT = 509, + CACHE_DICTIONARY_UPDATE_FAIL = 510, + UNKNOWN_ROLE = 511, + SET_NON_GRANTED_ROLE = 512, + UNKNOWN_PART_TYPE = 513, + ACCESS_STORAGE_FOR_INSERTION_NOT_FOUND = 514, + INCORRECT_ACCESS_ENTITY_DEFINITION = 515, + AUTHENTICATION_FAILED = 516, + CANNOT_ASSIGN_ALTER = 517, + CANNOT_COMMIT_OFFSET = 518, + NO_REMOTE_SHARD_AVAILABLE = 519, + CANNOT_DETACH_DICTIONARY_AS_TABLE = 520, + ATOMIC_RENAME_FAIL = 521, + UNKNOWN_ROW_POLICY = 523, + ALTER_OF_COLUMN_IS_FORBIDDEN = 524, + INCORRECT_DISK_INDEX = 525, + NO_SUITABLE_FUNCTION_IMPLEMENTATION = 527, + CASSANDRA_INTERNAL_ERROR = 528, + NOT_A_LEADER = 529, + CANNOT_CONNECT_RABBITMQ = 530, + CANNOT_FSTAT = 531, + LDAP_ERROR = 532, + UNKNOWN_RAID_TYPE = 535, + CANNOT_RESTORE_FROM_FIELD_DUMP = 536, + ILLEGAL_MYSQL_VARIABLE = 537, + MYSQL_SYNTAX_ERROR = 538, + CANNOT_BIND_RABBITMQ_EXCHANGE = 539, + CANNOT_DECLARE_RABBITMQ_EXCHANGE = 540, + CANNOT_CREATE_RABBITMQ_QUEUE_BINDING = 541, + CANNOT_REMOVE_RABBITMQ_EXCHANGE = 542, + UNKNOWN_MYSQL_DATATYPES_SUPPORT_LEVEL = 543, + ROW_AND_ROWS_TOGETHER = 544, + FIRST_AND_NEXT_TOGETHER = 545, + NO_ROW_DELIMITER = 546, + INVALID_RAID_TYPE = 547, + UNKNOWN_VOLUME = 548, + DATA_TYPE_CANNOT_BE_USED_IN_KEY = 549, + UNRECOGNIZED_ARGUMENTS = 552, + LZMA_STREAM_ENCODER_FAILED = 553, + LZMA_STREAM_DECODER_FAILED = 554, + ROCKSDB_ERROR = 555, + SYNC_MYSQL_USER_ACCESS_ERROR = 556, + UNKNOWN_UNION = 557, + EXPECTED_ALL_OR_DISTINCT = 558, + INVALID_GRPC_QUERY_INFO = 559, + ZSTD_ENCODER_FAILED = 560, + ZSTD_DECODER_FAILED = 561, + TLD_LIST_NOT_FOUND = 562, + CANNOT_READ_MAP_FROM_TEXT = 563, + INTERSERVER_SCHEME_DOESNT_MATCH = 564, + TOO_MANY_PARTITIONS = 565, + CANNOT_RMDIR = 566, + DUPLICATED_PART_UUIDS = 567, + RAFT_ERROR = 568, + MULTIPLE_COLUMNS_SERIALIZED_TO_SAME_PROTOBUF_FIELD = 569, + DATA_TYPE_INCOMPATIBLE_WITH_PROTOBUF_FIELD = 570, + DATABASE_REPLICATION_FAILED = 571, + TOO_MANY_QUERY_PLAN_OPTIMIZATIONS = 572, + EPOLL_ERROR = 573, + DISTRIBUTED_TOO_MANY_PENDING_BYTES = 574, + UNKNOWN_SNAPSHOT = 575, + KERBEROS_ERROR = 576, + INVALID_SHARD_ID = 577, + INVALID_FORMAT_INSERT_QUERY_WITH_DATA = 578, + INCORRECT_PART_TYPE = 579, + CANNOT_SET_ROUNDING_MODE = 580, + TOO_LARGE_DISTRIBUTED_DEPTH = 581, + NO_SUCH_PROJECTION_IN_TABLE = 582, + ILLEGAL_PROJECTION = 583, + PROJECTION_NOT_USED = 584, + CANNOT_PARSE_YAML = 585, + CANNOT_CREATE_FILE = 586, + CONCURRENT_ACCESS_NOT_SUPPORTED = 587, + DISTRIBUTED_BROKEN_BATCH_INFO = 588, + DISTRIBUTED_BROKEN_BATCH_FILES = 589, + CANNOT_SYSCONF = 590, + SQLITE_ENGINE_ERROR = 591, + DATA_ENCRYPTION_ERROR = 592, + ZERO_COPY_REPLICATION_ERROR = 593, + BZIP2_STREAM_DECODER_FAILED = 594, + BZIP2_STREAM_ENCODER_FAILED = 595, + INTERSECT_OR_EXCEPT_RESULT_STRUCTURES_MISMATCH = 596, + NO_SUCH_ERROR_CODE = 597, + BACKUP_ALREADY_EXISTS = 598, + BACKUP_NOT_FOUND = 599, + BACKUP_VERSION_NOT_SUPPORTED = 600, + BACKUP_DAMAGED = 601, + NO_BASE_BACKUP = 602, + WRONG_BASE_BACKUP = 603, + BACKUP_ENTRY_ALREADY_EXISTS = 604, + BACKUP_ENTRY_NOT_FOUND = 605, + BACKUP_IS_EMPTY = 606, + CANNOT_RESTORE_DATABASE = 607, + CANNOT_RESTORE_TABLE = 608, + FUNCTION_ALREADY_EXISTS = 609, + CANNOT_DROP_FUNCTION = 610, + CANNOT_CREATE_RECURSIVE_FUNCTION = 611, + POSTGRESQL_CONNECTION_FAILURE = 614, + CANNOT_ADVISE = 615, + UNKNOWN_READ_METHOD = 616, + LZ4_ENCODER_FAILED = 617, + LZ4_DECODER_FAILED = 618, + POSTGRESQL_REPLICATION_INTERNAL_ERROR = 619, + QUERY_NOT_ALLOWED = 620, + CANNOT_NORMALIZE_STRING = 621, + CANNOT_PARSE_CAPN_PROTO_SCHEMA = 622, + CAPN_PROTO_BAD_CAST = 623, + BAD_FILE_TYPE = 624, + IO_SETUP_ERROR = 625, + CANNOT_SKIP_UNKNOWN_FIELD = 626, + BACKUP_ENGINE_NOT_FOUND = 627, + OFFSET_FETCH_WITHOUT_ORDER_BY = 628, + HTTP_RANGE_NOT_SATISFIABLE = 629, + HAVE_DEPENDENT_OBJECTS = 630, + UNKNOWN_FILE_SIZE = 631, + UNEXPECTED_DATA_AFTER_PARSED_VALUE = 632, + QUERY_IS_NOT_SUPPORTED_IN_WINDOW_VIEW = 633, + MONGODB_ERROR = 634, + CANNOT_POLL = 635, + CANNOT_EXTRACT_TABLE_STRUCTURE = 636, + INVALID_TABLE_OVERRIDE = 637, + SNAPPY_UNCOMPRESS_FAILED = 638, + SNAPPY_COMPRESS_FAILED = 639, + NO_HIVEMETASTORE = 640, + CANNOT_APPEND_TO_FILE = 641, + CANNOT_PACK_ARCHIVE = 642, + CANNOT_UNPACK_ARCHIVE = 643, + NUMBER_OF_DIMENSIONS_MISMATCHED = 645, + CANNOT_BACKUP_TABLE = 647, + WRONG_DDL_RENAMING_SETTINGS = 648, + INVALID_TRANSACTION = 649, + SERIALIZATION_ERROR = 650, + CAPN_PROTO_BAD_TYPE = 651, + ONLY_NULLS_WHILE_READING_SCHEMA = 652, + CANNOT_PARSE_BACKUP_SETTINGS = 653, + WRONG_BACKUP_SETTINGS = 654, + FAILED_TO_SYNC_BACKUP_OR_RESTORE = 655, + UNKNOWN_STATUS_OF_TRANSACTION = 659, + HDFS_ERROR = 660, + CANNOT_SEND_SIGNAL = 661, + FS_METADATA_ERROR = 662, + INCONSISTENT_METADATA_FOR_BACKUP = 663, + ACCESS_STORAGE_DOESNT_ALLOW_BACKUP = 664, + CANNOT_CONNECT_NATS = 665, + NOT_INITIALIZED = 667, + INVALID_STATE = 668, + NAMED_COLLECTION_DOESNT_EXIST = 669, + NAMED_COLLECTION_ALREADY_EXISTS = 670, + NAMED_COLLECTION_IS_IMMUTABLE = 671, + INVALID_SCHEDULER_NODE = 672, + RESOURCE_ACCESS_DENIED = 673, + RESOURCE_NOT_FOUND = 674, + CANNOT_PARSE_IPV4 = 675, + CANNOT_PARSE_IPV6 = 676, + THREAD_WAS_CANCELED = 677, + IO_URING_INIT_FAILED = 678, + IO_URING_SUBMIT_ERROR = 679, + MIXED_ACCESS_PARAMETER_TYPES = 690, + UNKNOWN_ELEMENT_OF_ENUM = 691, + TOO_MANY_MUTATIONS = 692, + AWS_ERROR = 693, + ASYNC_LOAD_CYCLE = 694, + ASYNC_LOAD_FAILED = 695, + ASYNC_LOAD_CANCELED = 696, + CANNOT_RESTORE_TO_NONENCRYPTED_DISK = 697, + INVALID_REDIS_STORAGE_TYPE = 698, + INVALID_REDIS_TABLE_STRUCTURE = 699, + USER_SESSION_LIMIT_EXCEEDED = 700, + CLUSTER_DOESNT_EXIST = 701, + CLIENT_INFO_DOES_NOT_MATCH = 702, + INVALID_IDENTIFIER = 703, + QUERY_CACHE_USED_WITH_NONDETERMINISTIC_FUNCTIONS = 704, + // TABLE_NOT_EMPTY = 705, + // LIBSSH_ERROR = 706, + // GCP_ERROR = 707, + // ILLEGAL_STATISTIC = 708, + // CANNOT_GET_REPLICATED_DATABASE_SNAPSHOT = 709, + // FAULT_INJECTED = 710, + // FILECACHE_ACCESS_DENIED = 711, + // TOO_MANY_MATERIALIZED_VIEWS = 712, + // UNEXPECTED_CLUSTER = 714, + // CANNOT_DETECT_FORMAT = 715, + // CANNOT_FORGET_PARTITION = 716, + KEEPER_EXCEPTION = 999, + POCO_EXCEPTION = 1000, + STD_EXCEPTION = 1001, UNKNOWN_EXCEPTION = 1002, }; diff --git a/clickhouse/types/types.cpp b/clickhouse/types/types.cpp index 79e8be48..e1084fb0 100644 --- a/clickhouse/types/types.cpp +++ b/clickhouse/types/types.cpp @@ -161,9 +161,9 @@ uint64_t Type::GetTypeUniqueId() const { // 1. going to be the same // 2. going to be stored atomically - if (type_unique_id_.load(std::memory_order::memory_order_relaxed) == 0) { + if (type_unique_id_.load(std::memory_order_relaxed) == 0) { const auto name = GetName(); - type_unique_id_.store(CityHash64WithSeed(name.c_str(), name.size(), code_), std::memory_order::memory_order_relaxed); + type_unique_id_.store(CityHash64WithSeed(name.c_str(), name.size(), code_), std::memory_order_relaxed); } return type_unique_id_; diff --git a/clickhouse/types/types.h b/clickhouse/types/types.h index 423a6f70..12e2cbd5 100644 --- a/clickhouse/types/types.h +++ b/clickhouse/types/types.h @@ -251,6 +251,8 @@ class FixedStringType : public Type { std::string GetName() const { return std::string("FixedString(") + std::to_string(size_) + ")"; } + inline size_t GetSize() const { return size_; } + private: size_t size_; }; diff --git a/clickhouse/version.h b/clickhouse/version.h new file mode 100644 index 00000000..662de7f9 --- /dev/null +++ b/clickhouse/version.h @@ -0,0 +1,14 @@ +#pragma once + +#define CLICKHOUSE_CPP_VERSION_MAJOR 2 +#define CLICKHOUSE_CPP_VERSION_MINOR 5 +#define CLICKHOUSE_CPP_VERSION_PATCH 1 + +#define CLICKHOUSE_CPP_VERSION_BUILD 0 + +// Expecting each version component to be less than 99 +#define CLICKHOUSE_CPP_VERSION \ + CLICKHOUSE_CPP_VERSION_MAJOR * 100 * 100 * 100 \ + + CLICKHOUSE_CPP_VERSION_MINOR * 100 * 100 \ + + CLICKHOUSE_CPP_VERSION_PATCH * 100 \ + + CLICKHOUSE_CPP_VERSION_BUILD diff --git a/cmake/version.cmake b/cmake/version.cmake new file mode 100644 index 00000000..b7aee35d --- /dev/null +++ b/cmake/version.cmake @@ -0,0 +1,87 @@ +# Set version value for the project and validate that it matches version reported by git. + +# Reference values are taken from the version.h. +# So even if the library code is decoupled from the cmake-specific project, +# source files still have proper version information. + +function (regex_extract_matching_groups INPUT REGEX_STR) + string (REGEX MATCHALL "${REGEX_STR}" _ "${INPUT}") + if (NOT CMAKE_MATCH_0) + return() + endif() + + set (MATCH_GROUP_INDEX 0) + foreach (OUTPUT_VAR ${ARGN}) + math (EXPR MATCH_GROUP_INDEX "${MATCH_GROUP_INDEX}+1") + set (MATCH_GROUP_VALUE "${CMAKE_MATCH_${MATCH_GROUP_INDEX}}") + set ("${OUTPUT_VAR}" "${MATCH_GROUP_VALUE}" PARENT_SCOPE) + endforeach () +endfunction () + + +function(clickhouse_cpp_get_version) + # Extract all components of the version from the clickhouse/version.h + + file(READ ${CMAKE_CURRENT_SOURCE_DIR}/clickhouse/version.h VERSION_FILE_DATA) + + foreach (VERSION_COMPONENT + IN ITEMS + CLICKHOUSE_CPP_VERSION_MAJOR + CLICKHOUSE_CPP_VERSION_MINOR + CLICKHOUSE_CPP_VERSION_PATCH + CLICKHOUSE_CPP_VERSION_BUILD) + + regex_extract_matching_groups( + "${VERSION_FILE_DATA}" + "#define ${VERSION_COMPONENT} ([0-9]+)" + "${VERSION_COMPONENT}") + + set ("${VERSION_COMPONENT}" "${${VERSION_COMPONENT}}" PARENT_SCOPE) + endforeach () + + set(CLICKHOUSE_CPP_VERSION "${CLICKHOUSE_CPP_VERSION_MAJOR}.${CLICKHOUSE_CPP_VERSION_MINOR}.${CLICKHOUSE_CPP_VERSION_PATCH}" PARENT_SCOPE) +endfunction() + +clickhouse_cpp_get_version() + +function(clickhouse_cpp_check_library_version CHECK_MODE) +## Verify that current tag matches the version + + find_program (GIT git) + if (GIT) + execute_process( + COMMAND ${GIT} describe --tags + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_DESCRIBE_DATA + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + regex_extract_matching_groups( + "${GIT_DESCRIBE_DATA}" + "^v([0-9]+)\\.([0-9]+)\\.([0-9]+)(\\-([0-9]+).*)?" + VERSION_FROM_GIT_DESCRIBE_MAJOR + VERSION_FROM_GIT_DESCRIBE_MINOR + VERSION_FROM_GIT_DESCRIBE_PATCH + CLICKHOUSE_CPP_VERSION_COMMIT + ) + + if (NOT (VERSION_FROM_GIT_DESCRIBE_MAJOR AND VERSION_FROM_GIT_DESCRIBE_MINOR AND VERSION_FROM_GIT_DESCRIBE_PATCH)) + message (${CHECK_MODE} "version obtained from `git describe` doesn't look like a valid version: \"${GIT_DESCRIBE_DATA}\"") + return () + endif () + + set (EXPECTED_CLICKHOUSE_CPP_VERSION "${VERSION_FROM_GIT_DESCRIBE_MAJOR}.${VERSION_FROM_GIT_DESCRIBE_MINOR}.${VERSION_FROM_GIT_DESCRIBE_PATCH}") + if (NOT "${EXPECTED_CLICKHOUSE_CPP_VERSION}" STREQUAL ${CLICKHOUSE_CPP_VERSION}) + message(${CHECK_MODE} "update CLICKHOUSE_CPP_VERSION_ values in version.h.\n" +"git reports version as \"${GIT_DESCRIBE_DATA}\"," +" hence expecting version to be ${EXPECTED_CLICKHOUSE_CPP_VERSION}, " +" instead got ${CLICKHOUSE_CPP_VERSION}") + endif () + else () + message (${CHECK_MODE} "git is not found, can't verify library version") + endif () + + message("Version check passed: ${CLICKHOUSE_CPP_VERSION}") +endfunction() + +# clickhouse_cpp_check_library_version() diff --git a/ut/client_ut.cpp b/ut/client_ut.cpp index a9dd8190..3e08b17d 100644 --- a/ut/client_ut.cpp +++ b/ut/client_ut.cpp @@ -1,6 +1,9 @@ #include #include "clickhouse/base/socket.h" +#include "clickhouse/version.h" +#include "clickhouse/error_codes.h" + #include "readonly_client_test.h" #include "connection_failed_client_test.h" #include "ut/utils_comparison.h" @@ -19,12 +22,6 @@ using namespace clickhouse; -namespace clickhouse { -std::ostream & operator << (std::ostream & ostr, const Endpoint & endpoint) { - return ostr << endpoint.host << ":" << endpoint.port; -} -} - template std::shared_ptr createTableWithOneColumn(Client & client, const std::string & table_name, const std::string & column_name) { @@ -93,6 +90,21 @@ class ClientCase : public testing::TestWithParam { const std::string column_name = "test_column"; }; +TEST_P(ClientCase, Version) { + auto version = client_->GetVersion(); + EXPECT_NE(0, CLICKHOUSE_CPP_VERSION); + + EXPECT_GE(2, CLICKHOUSE_CPP_VERSION_MAJOR); + EXPECT_LE(0, CLICKHOUSE_CPP_VERSION_MINOR); + EXPECT_LE(0, CLICKHOUSE_CPP_VERSION_PATCH); + + EXPECT_EQ(CLICKHOUSE_CPP_VERSION_MAJOR, version.major); + EXPECT_EQ(CLICKHOUSE_CPP_VERSION_MINOR, version.minor); + EXPECT_EQ(CLICKHOUSE_CPP_VERSION_PATCH, version.patch); + EXPECT_EQ(CLICKHOUSE_CPP_VERSION_BUILD, version.build); + EXPECT_EQ(CLICKHOUSE_CPP_VERSION_PATCH, version.patch); +} + TEST_P(ClientCase, Array) { Block b; @@ -423,21 +435,29 @@ TEST_P(ClientCase, Nullable) { } TEST_P(ClientCase, Numbers) { - size_t num = 0; + try { + size_t num = 0; - client_->Select("SELECT number, number FROM system.numbers LIMIT 100000", [&num](const Block& block) - { - if (block.GetRowCount() == 0) { - return; - } - auto col = block[0]->As(); + client_->Select("SELECT number, number FROM system.numbers LIMIT 1000", [&num](const Block& block) + { + if (block.GetRowCount() == 0) { + return; + } + auto col = block[0]->As(); - for (size_t i = 0; i < col->Size(); ++i, ++num) { - EXPECT_EQ(num, col->At(i)); + for (size_t i = 0; i < col->Size(); ++i, ++num) { + EXPECT_EQ(num, col->At(i)); + } } - } - ); - EXPECT_EQ(100000U, num); + ); + EXPECT_EQ(1000U, num); + } + catch (const clickhouse::ServerError & e) { + if (e.GetCode() == ErrorCodes::ACCESS_DENIED) + GTEST_SKIP() << e.what() << " : " << GetParam(); + else + throw; + } } TEST_P(ClientCase, SimpleAggregateFunction) { @@ -451,7 +471,7 @@ TEST_P(ClientCase, SimpleAggregateFunction) { "CREATE TEMPORARY TABLE IF NOT EXISTS test_clickhouse_cpp_SimpleAggregateFunction (saf SimpleAggregateFunction(sum, UInt64))"); constexpr size_t EXPECTED_ROWS = 10; - client_->Execute("INSERT INTO test_clickhouse_cpp_SimpleAggregateFunction (saf) SELECT number FROM system.numbers LIMIT 10"); + client_->Execute("INSERT INTO test_clickhouse_cpp_SimpleAggregateFunction (saf) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)"); size_t total_rows = 0; client_->Select("Select * FROM test_clickhouse_cpp_SimpleAggregateFunction", [&total_rows](const Block & block) { @@ -1139,24 +1159,31 @@ TEST_P(ClientCase, OnProfileEvents) { } TEST_P(ClientCase, OnProfile) { - Query query("SELECT * FROM system.numbers LIMIT 10;"); - - std::optional profile; - query.OnProfile([&profile](const Profile & new_profile) { - profile = new_profile; - }); - - client_->Execute(query); + try { + Query query("SELECT * FROM system.numbers LIMIT 10;"); - // Make sure that profile event came through - ASSERT_NE(profile, std::nullopt); + std::optional profile; + query.OnProfile([&profile](const Profile & new_profile) { + profile = new_profile; + }); - EXPECT_GE(profile->rows, 10u); - EXPECT_GE(profile->blocks, 1u); - EXPECT_GT(profile->bytes, 1u); - EXPECT_GE(profile->rows_before_limit, 10u); - EXPECT_EQ(profile->applied_limit, true); - EXPECT_EQ(profile->calculated_rows_before_limit, true); + client_->Execute(query); + + // Make sure that profile event came through + ASSERT_NE(profile, std::nullopt); + + EXPECT_GE(profile->rows, 10u); + EXPECT_GE(profile->blocks, 1u); + EXPECT_GT(profile->bytes, 1u); + EXPECT_GE(profile->rows_before_limit, 10u); + EXPECT_EQ(profile->applied_limit, true); + EXPECT_EQ(profile->calculated_rows_before_limit, true); + } catch (const clickhouse::ServerError & e) { + if (e.GetCode() == ErrorCodes::ACCESS_DENIED) + GTEST_SKIP() << e.what() << " : " << GetParam(); + else + throw; + } } TEST_P(ClientCase, SelectAggregateFunction) { diff --git a/ut/column_array_ut.cpp b/ut/column_array_ut.cpp index 001cc62e..6fe0bd19 100644 --- a/ut/column_array_ut.cpp +++ b/ut/column_array_ut.cpp @@ -313,3 +313,90 @@ TEST(ColumnArrayT, Wrap_UInt64_2D) { EXPECT_TRUE(CompareRecursive(values, array)); } + +TEST(ColumnArrayT, left_value_no_move) { + std::string value0 = "000000000000000000"; + std::string value1 = "111111111111111111"; + std::string value2 = "222222222222222222"; + std::vector> all_values{ + { value0, value1, value2}, + { value0, value1, value2}, + { value0, value1, value2} + }; + size_t origin_size = 3; + auto array = std::make_shared>>(); + array->Append(all_values); + EXPECT_EQ(3u, (*array)[0][0].size()); + EXPECT_EQ(3u, (*array)[0][1].size()); + EXPECT_EQ(3u, (*array)[0][2].size()); + + EXPECT_EQ(value0, (*array)[0][0][0]); + EXPECT_EQ(value1, (*array)[0][1][1]); + EXPECT_EQ(value2, (*array)[0][2][2]); + + for (const auto& values : all_values) { + EXPECT_EQ(origin_size, values.size()); + } + + EXPECT_EQ(origin_size, all_values.size()); + for (const auto& values : all_values) { + EXPECT_EQ(values[0], value0); + EXPECT_EQ(values[1], value1); + EXPECT_EQ(values[2], value2); + } +} + +TEST(ColumnArrayT, right_value_move) { + std::string value0 = "000000000000000000"; + std::string value1 = "111111111111111111"; + std::string value2 = "222222222222222222"; + std::vector> all_values{ + { value0, value1, value2}, + { value0, value1, value2}, + { value0, value1, value2} + }; + auto array = std::make_shared>>(); + array->Append(std::move(all_values)); + EXPECT_EQ(3u, (*array)[0][0].size()); + EXPECT_EQ(3u, (*array)[0][1].size()); + EXPECT_EQ(3u, (*array)[0][2].size()); + + EXPECT_EQ(value0, (*array)[0][0][0]); + EXPECT_EQ(value1, (*array)[0][1][1]); + EXPECT_EQ(value2, (*array)[0][2][2]); + + // Here we don't care about the size of the container from which all values were moved-out. + //EXPECT_EQ(0u, all_values.size()); +} + +TEST(ColumnArrayT, const_right_value_no_move) { + std::string value0 = "000000000000000000"; + std::string value1 = "111111111111111111"; + std::string value2 = "222222222222222222"; + const std::vector> all_values{ + { value0, value1, value2}, + { value0, value1, value2}, + { value0, value1, value2} + }; + size_t origin_size = 3; + auto array = std::make_shared>>(); + array->Append(std::move(all_values)); + EXPECT_EQ(3u, (*array)[0][0].size()); + EXPECT_EQ(3u, (*array)[0][1].size()); + EXPECT_EQ(3u, (*array)[0][2].size()); + + EXPECT_EQ(value0, (*array)[0][0][0]); + EXPECT_EQ(value1, (*array)[0][1][1]); + EXPECT_EQ(value2, (*array)[0][2][2]); + + for (const auto& values : all_values) { + EXPECT_EQ(origin_size, values.size()); + } + + EXPECT_EQ(origin_size, all_values.size()); + for (const auto& values : all_values) { + EXPECT_EQ(values[0], value0); + EXPECT_EQ(values[1], value1); + EXPECT_EQ(values[2], value2); + } +} diff --git a/ut/columns_ut.cpp b/ut/columns_ut.cpp index 74dfcad3..4aa6aff1 100644 --- a/ut/columns_ut.cpp +++ b/ut/columns_ut.cpp @@ -102,6 +102,40 @@ TEST(ColumnsCase, FixedString_Append_LargeString) { EXPECT_ANY_THROW(col->Append("this is a long string")); } +TEST(ColumnsCase, FixedString_Type_Size_Eq0) { + const auto col = std::make_shared(0); + ASSERT_EQ(col->FixedSize(), col->Type()->As()->GetSize()); +} + +TEST(ColumnsCase, FixedString_Type_Size_Eq10) { + const auto col = std::make_shared(10); + ASSERT_EQ(col->FixedSize(), col->Type()->As()->GetSize()); +} + +TEST(ColumnsCase, StringInit) { + auto values = MakeStrings(); + auto col = std::make_shared(values); + + ASSERT_EQ(col->Size(), values.size()); + ASSERT_EQ(col->At(1), "ab"); + ASSERT_EQ(col->At(3), "abcd"); +} + +TEST(ColumnsCase, StringAppend) { + auto col = std::make_shared(); + const char* expected = "ufiudhf3493fyiudferyer3yrifhdflkdjfeuroe"; + std::string data(expected); + col->Append(data); + col->Append(std::move(data)); + col->Append("11"); + + ASSERT_EQ(col->Size(), 3u); + ASSERT_EQ(col->At(0), expected); + ASSERT_EQ(col->At(1), expected); + ASSERT_EQ(col->At(2), "11"); +} + + TEST(ColumnsCase, TupleAppend){ auto tuple1 = std::make_shared(std::vector({ std::make_shared(), @@ -685,6 +719,170 @@ TEST(ColumnsCase, ColumnDecimal128_from_string_overflow) { } +TEST(ColumnsCase, ColumnLowCardinalityString_Append_and_Read) { + const size_t items_count = 11; + ColumnLowCardinalityT col; + for (const auto & item : GenerateVector(items_count, &FooBarGenerator)) { + col.Append(item); + } + + ASSERT_EQ(col.Size(), items_count); + ASSERT_EQ(col.GetDictionarySize(), 8u + 1); // 8 unique items from sequence + 1 null-item + + for (size_t i = 0; i < items_count; ++i) { + ASSERT_EQ(col.At(i), FooBarGenerator(i)) << " at pos: " << i; + ASSERT_EQ(col[i], FooBarGenerator(i)) << " at pos: " << i; + } +} + +TEST(ColumnsCase, ColumnLowCardinalityString_Clear_and_Append) { + const size_t items_count = 11; + ColumnLowCardinalityT col; + for (const auto & item : GenerateVector(items_count, &FooBarGenerator)) + { + col.Append(item); + } + + col.Clear(); + ASSERT_EQ(col.Size(), 0u); + ASSERT_EQ(col.GetDictionarySize(), 1u); // null-item + + for (const auto & item : GenerateVector(items_count, &FooBarGenerator)) + { + col.Append(item); + } + + ASSERT_EQ(col.Size(), items_count); + ASSERT_EQ(col.GetDictionarySize(), 8u + 1); // 8 unique items from sequence + 1 null-item +} + +TEST(ColumnsCase, ColumnLowCardinalityString_Load) { + const size_t items_count = 10; + ColumnLowCardinalityT col; + + const auto & data = LOWCARDINALITY_STRING_FOOBAR_10_ITEMS_BINARY; + ArrayInput buffer(data.data(), data.size()); + + ASSERT_TRUE(col.Load(&buffer, items_count)); + + for (size_t i = 0; i < items_count; ++i) { + EXPECT_EQ(col.At(i), FooBarGenerator(i)) << " at pos: " << i; + } +} + +// This is temporary disabled since we are not 100% compatitable with ClickHouse +// on how we serailize LC columns, but we check interoperability in other tests (see client_ut.cpp) +TEST(ColumnsCase, DISABLED_ColumnLowCardinalityString_Save) { + const size_t items_count = 10; + ColumnLowCardinalityT col; + for (const auto & item : GenerateVector(items_count, &FooBarGenerator)) { + col.Append(item); + } + + ArrayOutput output(0, 0); + + const size_t expected_output_size = LOWCARDINALITY_STRING_FOOBAR_10_ITEMS_BINARY.size(); + // Enough space to account for possible overflow from both right and left sides. + std::string buffer(expected_output_size * 10, '\0');// = {'\0'}; + const char margin_content[sizeof(buffer)] = {'\0'}; + + const size_t left_margin_size = 10; + const size_t right_margin_size = sizeof(buffer) - left_margin_size - expected_output_size; + + // Since overflow from left side is less likely to happen, leave only tiny margin there. + auto write_pos = buffer.data() + left_margin_size; + const auto left_margin = buffer.data(); + const auto right_margin = write_pos + expected_output_size; + + output.Reset(write_pos, expected_output_size); + + EXPECT_NO_THROW(col.Save(&output)); + + // Left margin should be blank + EXPECT_EQ(std::string_view(margin_content, left_margin_size), std::string_view(left_margin, left_margin_size)); + // Right margin should be blank too + EXPECT_EQ(std::string_view(margin_content, right_margin_size), std::string_view(right_margin, right_margin_size)); + + // TODO: right now LC columns do not write indexes in the most compact way possible, so binary representation is a bit different + // (there might be other inconsistances too) + EXPECT_EQ(LOWCARDINALITY_STRING_FOOBAR_10_ITEMS_BINARY, std::string_view(write_pos, expected_output_size)); +} + +TEST(ColumnsCase, ColumnLowCardinalityString_SaveAndLoad) { + // Verify that we can load binary representation back + ColumnLowCardinalityT col; + + const auto items = GenerateVector(10, &FooBarGenerator); + for (const auto & item : items) { + col.Append(item); + } + + char buffer[256] = {'\0'}; // about 3 times more space than needed for this set of values. + { + ArrayOutput output(buffer, sizeof(buffer)); + EXPECT_NO_THROW(col.Save(&output)); + } + + col.Clear(); + + { + // Load the data back + ArrayInput input(buffer, sizeof(buffer)); + EXPECT_TRUE(col.Load(&input, items.size())); + } + + for (size_t i = 0; i < items.size(); ++i) { + EXPECT_EQ(col.At(i), items[i]) << " at pos: " << i; + } +} + +TEST(ColumnsCase, ColumnLowCardinalityString_WithEmptyString_1) { + // Verify that when empty string is added to a LC column it can be retrieved back as empty string. + ColumnLowCardinalityT col; + const auto values = GenerateVector(10, AlternateGenerators(SameValueGenerator(""), FooBarGenerator)); + for (const auto & item : values) { + col.Append(item); + } + + for (size_t i = 0; i < values.size(); ++i) { + EXPECT_EQ(values[i], col.At(i)) << " at pos: " << i; + } +} + +TEST(ColumnsCase, ColumnLowCardinalityString_WithEmptyString_2) { + // Verify that when empty string is added to a LC column it can be retrieved back as empty string. + // (Ver2): Make sure that outcome doesn't depend if empty values are on odd positions + ColumnLowCardinalityT col; + const auto values = GenerateVector(10, AlternateGenerators(FooBarGenerator, SameValueGenerator(""))); + for (const auto & item : values) { + col.Append(item); + } + + for (size_t i = 0; i < values.size(); ++i) { + EXPECT_EQ(values[i], col.At(i)) << " at pos: " << i; + } +} + +TEST(ColumnsCase, ColumnLowCardinalityString_WithEmptyString_3) { + // When we have many leading empty strings and some non-empty values. + ColumnLowCardinalityT col; + const auto values = ConcatSequences(GenerateVector(100, SameValueGenerator("")), GenerateVector(5, FooBarGenerator)); + for (const auto & item : values) { + col.Append(item); + } + + for (size_t i = 0; i < values.size(); ++i) { + EXPECT_EQ(values[i], col.At(i)) << " at pos: " << i; + } +} + +TEST(ColumnsCase, ColumnLowCardinalityFixedString_Type_Size_Eq) { + const size_t fixed_size = 10; + const auto col = std::make_shared>(fixed_size); + + ASSERT_EQ(fixed_size, col->GetNestedType()->As()->GetSize()); +} + TEST(ColumnsCase, ColumnTupleT) { using TestTuple = ColumnTupleT;