diff --git a/ut/CMakeLists.txt b/ut/CMakeLists.txt index a30032af..86066965 100644 --- a/ut/CMakeLists.txt +++ b/ut/CMakeLists.txt @@ -19,6 +19,7 @@ SET ( clickhouse-cpp-ut-src array_of_low_cardinality_tests.cpp CreateColumnByType_ut.cpp Column_ut.cpp + roundtrip_column.cpp utils.cpp value_generators.cpp diff --git a/ut/Column_ut.cpp b/ut/Column_ut.cpp index 46665c9b..de8a21ac 100644 --- a/ut/Column_ut.cpp +++ b/ut/Column_ut.cpp @@ -13,9 +13,12 @@ #include #include // for ipv4-ipv6 platform-specific stuff +#include + #include #include "utils.h" +#include "roundtrip_column.h" #include "value_generators.h" namespace { @@ -262,3 +265,35 @@ TYPED_TEST(GenericColumnTest, LoadAndSave) { EXPECT_TRUE(CompareRecursive(*column_A, *column_B)); } + +const auto LocalHostEndpoint = ClientOptions() + .SetHost( getEnvOrDefault("CLICKHOUSE_HOST", "localhost")) + .SetPort( getEnvOrDefault("CLICKHOUSE_PORT", "9000")) + .SetUser( getEnvOrDefault("CLICKHOUSE_USER", "default")) + .SetPassword( getEnvOrDefault("CLICKHOUSE_PASSWORD", "")) + .SetDefaultDatabase(getEnvOrDefault("CLICKHOUSE_DB", "default")); + +TYPED_TEST(GenericColumnTest, RoundTrip) { + auto [column, values] = this->MakeColumnWithValues(100); + EXPECT_EQ(values.size(), column->Size()); + + clickhouse::Client client(LocalHostEndpoint); + + if constexpr (std::is_same_v) { + // Date32 first appeared in v21.9.2.17-stable + const auto server_info = client.GetServerInfo(); + if (versionNumber(server_info) < versionNumber(21, 9)) { + GTEST_SKIP() << "Date32 is availble since v21.9.2.17-stable and can't be tested against server: " << server_info; + } + } + + if constexpr (std::is_same_v) { + const auto server_info = client.GetServerInfo(); + if (versionNumber(server_info) < versionNumber(21, 7)) { + GTEST_SKIP() << "ColumnInt128 is availble since v21.7.2.7-stable and can't be tested against server: " << server_info; + } + } + + auto result_typed = RoundtripColumnValues(client, column)->template AsStrict(); + EXPECT_TRUE(CompareRecursive(*column, *result_typed)); +} diff --git a/ut/array_of_low_cardinality_tests.cpp b/ut/array_of_low_cardinality_tests.cpp index 59d3d26c..56171236 100644 --- a/ut/array_of_low_cardinality_tests.cpp +++ b/ut/array_of_low_cardinality_tests.cpp @@ -87,15 +87,19 @@ TEST(ArrayOfLowCardinality, InsertAndQuery) { client.Insert("array_lc", block); client.Select("SELECT * FROM array_lc", [&](const Block& bl) { - for (size_t c = 0; c < bl.GetRowCount(); ++c) { - auto col = bl[0]->As()->GetAsColumn(c); - for (size_t i = 0; i < col->Size(); ++i) { - auto stringColumn = col->As(); - const auto string = stringColumn->At(i); - + for (size_t c = 0; c < bl.GetRowCount(); ++c) { + auto col = bl[0]->As()->GetAsColumn(c); + for (size_t i = 0; i < col->Size(); ++i) { + if (auto string_column = col->As()) { + const auto string = string_column->At(i); + ASSERT_EQ(testData[c][i], string); + } else if (auto lc_string_column = col->As>()) { + const auto string = lc_string_column->At(i); ASSERT_EQ(testData[c][i], string); + } else { + FAIL() << "Unexpected column type: " << col->Type()->GetName(); } } - } - ); -} \ No newline at end of file + } + }); +} diff --git a/ut/client_ut.cpp b/ut/client_ut.cpp index 82032377..5cc1b81a 100644 --- a/ut/client_ut.cpp +++ b/ut/client_ut.cpp @@ -3,42 +3,15 @@ #include "readonly_client_test.h" #include "connection_failed_client_test.h" #include "utils.h" +#include "roundtrip_column.h" #include -#include #include #include using namespace clickhouse; -namespace { - -uint64_t versionNumber( - uint64_t version_major, - uint64_t version_minor, - uint64_t version_patch = 0, - uint64_t revision = 0) { - - // in this case version_major can be up to 1000 - static auto revision_decimal_places = 8; - static auto patch_decimal_places = 4; - static auto minor_decimal_places = 4; - - auto const result = version_major * static_cast(std::pow(10, minor_decimal_places + patch_decimal_places + revision_decimal_places)) - + version_minor * static_cast(std::pow(10, patch_decimal_places + revision_decimal_places)) - + version_patch * static_cast(std::pow(10, revision_decimal_places)) - + revision; - - return result; -} - -uint64_t versionNumber(const ServerInfo & server_info) { - return versionNumber(server_info.version_major, server_info.version_minor, server_info.version_patch, server_info.revision); -} - -} - // Use value-parameterized tests to run same tests with different client // options. class ClientCase : public testing::TestWithParam { @@ -978,35 +951,6 @@ TEST_P(ClientCase, DISABLED_ArrayArrayUInt64) { } } -ColumnRef RoundtripColumnValues(Client& client, ColumnRef expected) { - // Create a temporary table with a single column - // insert values from `expected` - // select and aggregate all values from block into `result` column - auto result = expected->CloneEmpty(); - - const std::string type_name = result->GetType().GetName(); - client.Execute("DROP TEMPORARY TABLE IF EXISTS temporary_roundtrip_table;"); - client.Execute("CREATE TEMPORARY TABLE IF NOT EXISTS temporary_roundtrip_table (col " + type_name + ");"); - { - Block block; - block.AppendColumn("col", expected); - block.RefreshRowCount(); - client.Insert("temporary_roundtrip_table", block); - } - - client.Select("SELECT col FROM temporary_roundtrip_table", [&result](const Block& b) { - if (b.GetRowCount() == 0) - return; - - ASSERT_EQ(1u, b.GetColumnCount()); - result->Append(b[0]); - }); - - EXPECT_EQ(expected->GetType(), result->GetType()); - EXPECT_EQ(expected->Size(), result->Size()); - return result; -} - TEST_P(ClientCase, RoundtripArrayTUint64) { auto array = std::make_shared>(); array->Append({0, 1, 2}); diff --git a/ut/roundtrip_column.cpp b/ut/roundtrip_column.cpp new file mode 100644 index 00000000..c4685a3b --- /dev/null +++ b/ut/roundtrip_column.cpp @@ -0,0 +1,40 @@ +#include "roundtrip_column.h" + +#include +#include + +#include + +namespace { +using namespace clickhouse; +} + +ColumnRef RoundtripColumnValues(Client& client, ColumnRef expected) { + // Create a temporary table with a single column + // insert values from `expected` + // select and aggregate all values from block into `result` column + auto result = expected->CloneEmpty(); + + const std::string type_name = result->GetType().GetName(); + client.Execute("DROP TEMPORARY TABLE IF EXISTS temporary_roundtrip_table;"); + client.Execute("CREATE TEMPORARY TABLE IF NOT EXISTS temporary_roundtrip_table (col " + type_name + ");"); + { + Block block; + block.AppendColumn("col", expected); + block.RefreshRowCount(); + client.Insert("temporary_roundtrip_table", block); + } + + client.Select("SELECT col FROM temporary_roundtrip_table", [&result](const Block& b) { + if (b.GetRowCount() == 0) + return; + + ASSERT_EQ(1u, b.GetColumnCount()); + result->Append(b[0]); + }); + + EXPECT_EQ(expected->GetType(), result->GetType()); + EXPECT_EQ(expected->Size(), result->Size()); + + return result; +} diff --git a/ut/roundtrip_column.h b/ut/roundtrip_column.h new file mode 100644 index 00000000..30097997 --- /dev/null +++ b/ut/roundtrip_column.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace clickhouse { + class Client; +} + +clickhouse::ColumnRef RoundtripColumnValues(clickhouse::Client& client, clickhouse::ColumnRef expected); diff --git a/ut/utils.cpp b/ut/utils.cpp index a5ef5cfd..07ae5174 100644 --- a/ut/utils.cpp +++ b/ut/utils.cpp @@ -18,6 +18,7 @@ #include #include + namespace { using namespace clickhouse; std::ostream & printColumnValue(const ColumnRef& c, const size_t row, std::ostream & ostr); @@ -266,3 +267,7 @@ std::ostream & operator<<(std::ostream & ostr, const ServerInfo & server_info) { } } + +uint64_t versionNumber(const ServerInfo & server_info) { + return versionNumber(server_info.version_major, server_info.version_minor, server_info.version_patch, server_info.revision); +} diff --git a/ut/utils.h b/ut/utils.h index 80348f76..f0a6194f 100644 --- a/ut/utils.h +++ b/ut/utils.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include "utils_meta.h" #include "utils_comparison.h" @@ -12,12 +11,14 @@ #include #include #include +#include #include #include namespace clickhouse { + class Client; class Block; class Type; struct ServerInfo; @@ -136,4 +137,23 @@ std::ostream& operator<<(std::ostream & ostr, const PrintContainer& print_con return ostr << "]"; } +inline uint64_t versionNumber( + uint64_t version_major, + uint64_t version_minor, + uint64_t version_patch = 0, + uint64_t revision = 0) { + // in this case version_major can be up to 1000 + static auto revision_decimal_places = 8; + static auto patch_decimal_places = 4; + static auto minor_decimal_places = 4; + + auto const result = version_major * static_cast(std::pow(10, minor_decimal_places + patch_decimal_places + revision_decimal_places)) + + version_minor * static_cast(std::pow(10, patch_decimal_places + revision_decimal_places)) + + version_patch * static_cast(std::pow(10, revision_decimal_places)) + + revision; + + return result; +} + +uint64_t versionNumber(const clickhouse::ServerInfo & server_info); diff --git a/ut/value_generators.h b/ut/value_generators.h index d7f85b65..a3004102 100644 --- a/ut/value_generators.h +++ b/ut/value_generators.h @@ -2,6 +2,7 @@ #include // for ipv4-ipv6 platform-specific stuff #include +#include #include "utils.h"