From e138d2ed47867a1cfd8671a9471caaada1274c64 Mon Sep 17 00:00:00 2001 From: Roy Bellingan Date: Wed, 2 Sep 2026 11:45:31 +0100 Subject: [PATCH 1/3] c++ complain that ciso646 is non standard, and version should be used --- contrib/absl/absl/base/options.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/absl/absl/base/options.h b/contrib/absl/absl/base/options.h index 230bf1ee..9e5b26ff 100644 --- a/contrib/absl/absl/base/options.h +++ b/contrib/absl/absl/base/options.h @@ -70,8 +70,12 @@ // Include a standard library header to allow configuration based on the // standard library in use. #ifdef __cplusplus +#if __cplusplus >= 202002L +#include +#else #include #endif +#endif // ----------------------------------------------------------------------------- // Type Compatibility Options From ee3a87242d4de558a3e569fae38eca24c5d23d57 Mon Sep 17 00:00:00 2001 From: Andrew Slabko Date: Fri, 4 Sep 2026 17:25:30 +0200 Subject: [PATCH 2/3] Add CH_NON_OPTIONAL_CURRENT_ENDPOINT build option When enabled, Client::GetCurrentEndpoint() returns Endpoint by value instead of the legacy std::optional. Defaults to OFF for backward compatibility. - Declare the CMake option and propagate it as a PUBLIC compile definition, mirroring CH_MAP_BOOL_TO_UINT8 / CH_USE_ABSEIL_FOR_BIGNUM - Enable the option unconditionally in BUILD.bazel (no 2.x compatibility promised there) and document the option in README - Fix missing Client:: qualifier on the by-value overload - Make unit tests and tests/simple compile under both modes --- BUILD.bazel | 4 ++++ CMakeLists.txt | 1 + README.md | 8 +++++++- clickhouse/CMakeLists.txt | 5 +++++ clickhouse/client.cpp | 6 ++++++ clickhouse/client.h | 4 ++++ tests/simple/main.cpp | 4 ++++ ut/client_ut.cpp | 24 +++++++++++++++++------- 8 files changed, 48 insertions(+), 8 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index b51d0235..cba4eaed 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -114,6 +114,10 @@ cc_library( # Users are free to include Abseil in their own projects and convert values produced by this # library to the corresponding Abseil types. "CH_USE_ABSEIL_FOR_BIGNUM=0", + # `Client::GetCurrentEndpoint()` returns `Endpoint` by value rather than the legacy + # `std::optional`. The Bazel build does not promise backward compatibility with + # the 2.x API, so it always uses the new form (CMake's `CH_NON_OPTIONAL_CURRENT_ENDPOINT=ON`). + "CH_NON_OPTIONAL_CURRENT_ENDPOINT=1", ] + select({ # `WITH_OPENSSL` enables the TLS code paths in client.cpp / # sslsocket.cpp (same macro as the CMake option). `USE_BORINGSSL` diff --git a/CMakeLists.txt b/CMakeLists.txt index fd88ff3f..15446210 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ 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) OPTION (DISABLE_CLANG_LIBC_WORKAROUND "Disable linking compiler-rt & gcc_s if using clang & libstdc++" OFF) OPTION (CH_MAP_BOOL_TO_UINT8 "Map ClickHouse Bool type to UInt8 instead of exposing a distinct Bool API." ON) +OPTION (CH_NON_OPTIONAL_CURRENT_ENDPOINT "Make Client::GetCurrentEndpoint() return Endpoint by value instead of std::optional." OFF) PROJECT (CLICKHOUSE-CLIENT VERSION "${CLICKHOUSE_CPP_VERSION}" diff --git a/README.md b/README.md index 80a10283..0ca19cd7 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Here is an example with recommended settings; ```sh $ mkdir build . $ cd build -$ cmake .. -DCH_USE_ABSEIL_FOR_BIGNUM=NO -DCH_MAP_BOOL_TO_UINT8=NO +$ cmake .. -DCH_USE_ABSEIL_FOR_BIGNUM=NO -DCH_MAP_BOOL_TO_UINT8=NO -DCH_NON_OPTIONAL_CURRENT_ENDPOINT=YES $ make ``` @@ -39,6 +39,10 @@ The command above disables two legacy CMake defaults, `CH_USE_ABSEIL_FOR_BIGNUM` the defaults temporarily, but should migrate to this configuration as this behavior will be removed in the future versions of the library. +It also enables `CH_NON_OPTIONAL_CURRENT_ENDPOINT`, which makes `Client::GetCurrentEndpoint()` +return `Endpoint` by value instead of the legacy `std::optional`. The option defaults to +`OFF` for backward compatibility; the optional form will be removed in future versions. + Please refer to the workflows for the reference on dependencies/build options - https://github.com/ClickHouse/clickhouse-cpp/blob/master/.github/workflows/linux.yml - https://github.com/ClickHouse/clickhouse-cpp/blob/master/.github/workflows/windows_msvc.yml @@ -99,6 +103,7 @@ project(application-example LANGUAGES CXX) set(CH_USE_ABSEIL_FOR_BIGNUM OFF) set(CH_MAP_BOOL_TO_UINT8 OFF) +set(CH_NON_OPTIONAL_CURRENT_ENDPOINT ON) add_subdirectory(contrib/clickhouse-cpp) @@ -118,6 +123,7 @@ include(FetchContent) set(CH_USE_ABSEIL_FOR_BIGNUM OFF) set(CH_MAP_BOOL_TO_UINT8 OFF) +set(CH_NON_OPTIONAL_CURRENT_ENDPOINT ON) FetchContent_Declare( clickhouse_cpp diff --git a/clickhouse/CMakeLists.txt b/clickhouse/CMakeLists.txt index 6664ee4f..7b6387cc 100644 --- a/clickhouse/CMakeLists.txt +++ b/clickhouse/CMakeLists.txt @@ -142,6 +142,11 @@ ELSE () TARGET_COMPILE_DEFINITIONS (clickhouse-cpp-lib PUBLIC CH_USE_ABSEIL_FOR_BIGNUM=0) ENDIF () +IF (CH_NON_OPTIONAL_CURRENT_ENDPOINT) + TARGET_COMPILE_DEFINITIONS (clickhouse-cpp-lib PUBLIC CH_NON_OPTIONAL_CURRENT_ENDPOINT=1) +ELSE () + TARGET_COMPILE_DEFINITIONS (clickhouse-cpp-lib PUBLIC CH_NON_OPTIONAL_CURRENT_ENDPOINT=0) +ENDIF () IF (NOT BUILD_SHARED_LIBS) ADD_LIBRARY (clickhouse-cpp-lib-static ALIAS clickhouse-cpp-lib) diff --git a/clickhouse/client.cpp b/clickhouse/client.cpp index 05f03bcd..8cbf68d7 100644 --- a/clickhouse/client.cpp +++ b/clickhouse/client.cpp @@ -1412,9 +1412,15 @@ void Client::ResetConnectionEndpoint() { impl_->ResetConnectionEndpoint(); } +#if CH_NON_OPTIONAL_CURRENT_ENDPOINT +Endpoint Client::GetCurrentEndpoint() const { + return impl_->GetCurrentEndpoint().value(); +} +#else const std::optional& Client::GetCurrentEndpoint() const { return impl_->GetCurrentEndpoint(); } +#endif const ServerInfo& Client::GetServerInfo() const { return impl_->GetServerInfo(); diff --git a/clickhouse/client.h b/clickhouse/client.h index 5e13d269..dfe31536 100644 --- a/clickhouse/client.h +++ b/clickhouse/client.h @@ -340,7 +340,11 @@ class Client { /// Get current endpoint, i.e. the last successfully connected endpoint. /// It remains optional for backward compatibility, but now always contains a value. +#if CH_NON_OPTIONAL_CURRENT_ENDPOINT + Endpoint GetCurrentEndpoint() const; +#else const std::optional& GetCurrentEndpoint() const; +#endif /// Try to reconnect to different endpoints one by one only one time. If it doesn't work, throw /// an exception. The function starts with the last successfully connected endpoint. diff --git a/tests/simple/main.cpp b/tests/simple/main.cpp index adc2c909..5e95433b 100644 --- a/tests/simple/main.cpp +++ b/tests/simple/main.cpp @@ -588,7 +588,11 @@ int main() { Client client(ClientOptions(localHostEndpoint) .SetPingBeforeQuery(true)); RunTests(client); +#if CH_NON_OPTIONAL_CURRENT_ENDPOINT + std::cout << "current endpoint : " << client.GetCurrentEndpoint().host << "\n"; +#else std::cout << "current endpoint : " << client.GetCurrentEndpoint().value().host << "\n"; +#endif } { diff --git a/ut/client_ut.cpp b/ut/client_ut.cpp index 0e5a020b..88ef5779 100644 --- a/ut/client_ut.cpp +++ b/ut/client_ut.cpp @@ -41,6 +41,16 @@ ClientBoolValue MakeClientBoolValue(bool value) { #endif } +// Client::GetCurrentEndpoint() returns either Endpoint or std::optional +// depending on CH_NON_OPTIONAL_CURRENT_ENDPOINT; normalize to Endpoint for tests. +Endpoint CurrentEndpoint(const Client & client) { +#if CH_NON_OPTIONAL_CURRENT_ENDPOINT + return client.GetCurrentEndpoint(); +#else + return client.GetCurrentEndpoint().value(); +#endif +} + template std::shared_ptr createTableWithOneColumn(Client & client, const std::string & table_name, const std::string & column_name) { @@ -1784,7 +1794,7 @@ TEST_P(ConnectionSuccessTestCase, SuccessConnectionEstablished) { try { client = std::make_unique(client_options); - auto endpoint = client->GetCurrentEndpoint().value(); + auto endpoint = CurrentEndpoint(*client); ASSERT_EQ("localhost", endpoint.host); ASSERT_EQ(9000u, endpoint.port); SUCCEED(); @@ -1866,27 +1876,27 @@ TEST(ResetConnectionEndpointTest, ReconnectsCurrentBeforeFailover) { // The initial connection selects the first endpoint. Client client(options, std::move(socket_factory)); - ASSERT_EQ(primary, client.GetCurrentEndpoint().value()); + ASSERT_EQ(primary, CurrentEndpoint(client)); // A healthy current endpoint is retried without advancing. adapter->SetFailEndpoint(std::nullopt); adapter->ClearConnectRequests(); client.ResetConnectionEndpoint(); - EXPECT_EQ(primary, client.GetCurrentEndpoint().value()); + EXPECT_EQ(primary, CurrentEndpoint(client)); EXPECT_EQ(std::vector{primary}, adapter->ConnectRequests()); // Failure of the current endpoint advances to the next endpoint. adapter->SetFailEndpoint(primary); adapter->ClearConnectRequests(); client.ResetConnectionEndpoint(); - EXPECT_EQ(secondary, client.GetCurrentEndpoint().value()); + EXPECT_EQ(secondary, CurrentEndpoint(client)); EXPECT_EQ((std::vector{primary, secondary}), adapter->ConnectRequests()); // Failure of the last endpoint wraps around to the first endpoint. adapter->SetFailEndpoint(secondary); adapter->ClearConnectRequests(); client.ResetConnectionEndpoint(); - EXPECT_EQ(primary, client.GetCurrentEndpoint().value()); + EXPECT_EQ(primary, CurrentEndpoint(client)); EXPECT_EQ((std::vector{secondary, primary}), adapter->ConnectRequests()); } @@ -1896,12 +1906,12 @@ TEST_P(ResetConnectionTestCase, ResetConnectionTest) { try { client = std::make_unique(client_options); - auto endpoint = client->GetCurrentEndpoint().value(); + auto endpoint = CurrentEndpoint(*client); ASSERT_EQ("localhost", endpoint.host); ASSERT_EQ(9000u, endpoint.port); client->ResetConnection(); - endpoint = client->GetCurrentEndpoint().value(); + endpoint = CurrentEndpoint(*client); ASSERT_EQ("localhost", endpoint.host); ASSERT_EQ(9000u, endpoint.port); From df3c3219ff532e9387559e208509b6964358d5da Mon Sep 17 00:00:00 2001 From: Andrew Slabko Date: Fri, 4 Sep 2026 17:31:42 +0200 Subject: [PATCH 3/3] Add CH_USE_3X_API umbrella build option CH_USE_3X_API=ON selects the 3.x API in one step by defaulting CH_MAP_BOOL_TO_UINT8=OFF, CH_USE_ABSEIL_FOR_BIGNUM=OFF and CH_NON_OPTIONAL_CURRENT_ENDPOINT=ON. Setting any of these to a conflicting value alongside CH_USE_3X_API=ON is a configuration error. Update README to recommend CH_USE_3X_API and document the mapping between the umbrella option and the individual ones. --- CMakeLists.txt | 30 +++++++++++++++++++++++++++--- README.md | 31 +++++++++++++++++-------------- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 15446210..b30ce1f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,6 @@ IF ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") ENDIF () OPTION (WITH_OPENSSL "Use OpenSSL for TLS connections" OFF) -OPTION (CH_USE_ABSEIL_FOR_BIGNUM "Use Google Abseil for wide (128-bit) integers" ON) OPTION (WITH_SYSTEM_ABSEIL "Use system Google Abseil, otherwise vendored part part of Google Abseil will be used" OFF) OPTION (WITH_SYSTEM_LZ4 "Use system LZ4" OFF) @@ -23,8 +22,33 @@ OPTION (WITH_SYSTEM_ZSTD "Use system ZSTD" 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) OPTION (DISABLE_CLANG_LIBC_WORKAROUND "Disable linking compiler-rt & gcc_s if using clang & libstdc++" OFF) -OPTION (CH_MAP_BOOL_TO_UINT8 "Map ClickHouse Bool type to UInt8 instead of exposing a distinct Bool API." ON) -OPTION (CH_NON_OPTIONAL_CURRENT_ENDPOINT "Make Client::GetCurrentEndpoint() return Endpoint by value instead of std::optional." OFF) + +# API compatibility options. The defaults preserve the legacy 2.x behaviour. CH_USE_3X_API switches +# all of them to the 3.x values at once; individual options may not be set to conflicting values. +OPTION (CH_USE_3X_API "Use the 3.x API: implies CH_MAP_BOOL_TO_UINT8=OFF, CH_USE_ABSEIL_FOR_BIGNUM=OFF, CH_NON_OPTIONAL_CURRENT_ENDPOINT=ON" OFF) +IF (CH_USE_3X_API) + SET (CH_3X_MAP_BOOL_TO_UINT8 OFF) + SET (CH_3X_USE_ABSEIL_FOR_BIGNUM OFF) + SET (CH_3X_NON_OPTIONAL_CURRENT_ENDPOINT ON) +ELSE () + SET (CH_3X_MAP_BOOL_TO_UINT8 ON) + SET (CH_3X_USE_ABSEIL_FOR_BIGNUM ON) + SET (CH_3X_NON_OPTIONAL_CURRENT_ENDPOINT OFF) +ENDIF () +OPTION (CH_MAP_BOOL_TO_UINT8 "Map ClickHouse Bool type to UInt8 instead of exposing a distinct Bool API." ${CH_3X_MAP_BOOL_TO_UINT8}) +OPTION (CH_USE_ABSEIL_FOR_BIGNUM "Use Google Abseil for wide (128-bit) integers" ${CH_3X_USE_ABSEIL_FOR_BIGNUM}) +OPTION (CH_NON_OPTIONAL_CURRENT_ENDPOINT "Make Client::GetCurrentEndpoint() return Endpoint by value instead of std::optional." ${CH_3X_NON_OPTIONAL_CURRENT_ENDPOINT}) + +IF (CH_USE_3X_API) + FOREACH (opt MAP_BOOL_TO_UINT8 USE_ABSEIL_FOR_BIGNUM NON_OPTIONAL_CURRENT_ENDPOINT) + IF ((CH_${opt} AND NOT CH_3X_${opt}) OR (NOT CH_${opt} AND CH_3X_${opt})) + MESSAGE (FATAL_ERROR + "CH_USE_3X_API=ON requires CH_${opt}=${CH_3X_${opt}}, but it is set to '${CH_${opt}}'. " + "Either drop the explicit CH_${opt} setting, or set it to ${CH_3X_${opt}}. " + "If the value comes from a previous configure run, delete CMakeCache.txt or pass -DCH_${opt}=${CH_3X_${opt}}.") + ENDIF () + ENDFOREACH () +ENDIF () PROJECT (CLICKHOUSE-CLIENT VERSION "${CLICKHOUSE_CPP_VERSION}" diff --git a/README.md b/README.md index 0ca19cd7..a3f29a23 100644 --- a/README.md +++ b/README.md @@ -30,18 +30,25 @@ Here is an example with recommended settings; ```sh $ mkdir build . $ cd build -$ cmake .. -DCH_USE_ABSEIL_FOR_BIGNUM=NO -DCH_MAP_BOOL_TO_UINT8=NO -DCH_NON_OPTIONAL_CURRENT_ENDPOINT=YES +$ cmake .. -DCH_USE_3X_API=YES $ make ``` -The command above disables two legacy CMake defaults, `CH_USE_ABSEIL_FOR_BIGNUM` and -`CH_MAP_BOOL_TO_UINT8`. New projects should set both options to `OFF`. Existing projects can keep -the defaults temporarily, but should migrate to this configuration as this behavior will be removed -in the future versions of the library. +`CH_USE_3X_API` selects the new 3.x API. As the project evolves we bring new changes to the +API; sometimes these require breaking changes. When that happens we keep the old API +unchanged by default and hide the changes behind specific flags. To enable all of these changes +at once, we recommend enabling `CH_USE_3X_API`, which will be the default API in version 3.0. -It also enables `CH_NON_OPTIONAL_CURRENT_ENDPOINT`, which makes `Client::GetCurrentEndpoint()` -return `Endpoint` by value instead of the legacy `std::optional`. The option defaults to -`OFF` for backward compatibility; the optional form will be removed in future versions. +Enabling this option is equivalent to setting the following individual options: + +| Option | 2.x default | 3.x value | Effect when set to the 3.x value | +|------------------------------------|-------------|-----------|-----------------------------------------------------------------------------------------| +| `CH_MAP_BOOL_TO_UINT8` | `ON` | `OFF` | ClickHouse `Bool` maps to `clickhouse::ColumnBool` instead of `ColumnUInt8` | +| `CH_USE_ABSEIL_FOR_BIGNUM` | `ON` | `OFF` | 128-bit integers use the self-contained implementation instead of Abseil | +| `CH_NON_OPTIONAL_CURRENT_ENDPOINT` | `OFF` | `ON` | `Client::GetCurrentEndpoint()` returns `Endpoint` by value instead of `std::optional` | + +The individual options can still be set one at a time for a gradual migration; however, when +`CH_USE_3X_API=ON` is given, setting any of them to a conflicting value is a configuration error. Please refer to the workflows for the reference on dependencies/build options - https://github.com/ClickHouse/clickhouse-cpp/blob/master/.github/workflows/linux.yml @@ -101,9 +108,7 @@ Then include it from your `CMakeLists.txt`: cmake_minimum_required(VERSION 3.13) project(application-example LANGUAGES CXX) -set(CH_USE_ABSEIL_FOR_BIGNUM OFF) -set(CH_MAP_BOOL_TO_UINT8 OFF) -set(CH_NON_OPTIONAL_CURRENT_ENDPOINT ON) +set(CH_USE_3X_API ON) add_subdirectory(contrib/clickhouse-cpp) @@ -121,9 +126,7 @@ project(application-example LANGUAGES CXX) include(FetchContent) -set(CH_USE_ABSEIL_FOR_BIGNUM OFF) -set(CH_MAP_BOOL_TO_UINT8 OFF) -set(CH_NON_OPTIONAL_CURRENT_ENDPOINT ON) +set(CH_USE_3X_API ON) FetchContent_Declare( clickhouse_cpp