diff --git a/clickhouse/columns/date.cpp b/clickhouse/columns/date.cpp index af3ccb20..c3476c7f 100644 --- a/clickhouse/columns/date.cpp +++ b/clickhouse/columns/date.cpp @@ -43,8 +43,8 @@ void ColumnDate::Append(ColumnRef column) { } } -std::vector &ColumnDate::GetRawVector() { - return data_->GetRawVector(); +std::vector& ColumnDate::GetWritableData() { + return data_->GetWritableData(); } void ColumnDate::Reserve(size_t new_cap) { @@ -122,8 +122,8 @@ void ColumnDate32::Append(ColumnRef column) { } } -std::vector & ColumnDate32::GetRawVector() { - return data_->GetRawVector(); +std::vector& ColumnDate32::GetWritableData() { + return data_->GetWritableData(); } void ColumnDate32::Reserve(size_t new_cap) { @@ -220,8 +220,8 @@ void ColumnDateTime::Append(ColumnRef column) { } } -std::vector & ColumnDateTime::GetRawVector() { - return data_->GetRawVector(); +std::vector& ColumnDateTime::GetWritableData() { + return data_->GetWritableData(); } void ColumnDateTime::Reserve(size_t new_cap) { diff --git a/clickhouse/columns/date.h b/clickhouse/columns/date.h index 0faca1ec..c6e32234 100644 --- a/clickhouse/columns/date.h +++ b/clickhouse/columns/date.h @@ -32,7 +32,7 @@ class ColumnDate : public Column { void Append(ColumnRef column) override; /// Get Raw Vector Contents - std::vector & GetRawVector(); + std::vector& GetWritableData(); /// Increase the capacity of the column void Reserve(size_t new_cap); @@ -89,7 +89,7 @@ class ColumnDate32 : public Column { int32_t RawAt(size_t n) const; /// Get Raw Vector Contents - std::vector & GetRawVector(); + std::vector& GetWritableData(); /// Increase the capacity of the column void Reserve(size_t new_cap); @@ -146,7 +146,7 @@ class ColumnDateTime : public Column { std::string Timezone() const; /// Get Raw Vector Contents - std::vector & GetRawVector(); + std::vector& GetWritableData(); /// Increase the capacity of the column void Reserve(size_t new_cap); diff --git a/clickhouse/columns/numeric.cpp b/clickhouse/columns/numeric.cpp index 57a32dd0..1c611c79 100644 --- a/clickhouse/columns/numeric.cpp +++ b/clickhouse/columns/numeric.cpp @@ -39,7 +39,7 @@ void ColumnVector::Erase(size_t pos, size_t count) { } template -std::vector & ColumnVector::GetRawVector() { +std::vector& ColumnVector::GetWritableData() { return data_; } diff --git a/clickhouse/columns/numeric.h b/clickhouse/columns/numeric.h index d3523614..1cbcca9c 100644 --- a/clickhouse/columns/numeric.h +++ b/clickhouse/columns/numeric.h @@ -31,7 +31,7 @@ class ColumnVector : public Column { void Erase(size_t pos, size_t count = 1); /// Get Raw Vector Contents - std::vector & GetRawVector(); + std::vector& GetWritableData(); /// Increase the capacity of the column void Reserve(size_t new_cap); diff --git a/ut/Column_ut.cpp b/ut/Column_ut.cpp index 6e5668e6..9eb3c7cf 100644 --- a/ut/Column_ut.cpp +++ b/ut/Column_ut.cpp @@ -16,10 +16,14 @@ #include #include +#include #include #include #include +#include "gtest/internal/gtest-internal.h" +#include "ut/utils_comparison.h" +#include "ut/utils_meta.h" #include "utils.h" #include "roundtrip_column.h" #include "value_generators.h" @@ -364,6 +368,82 @@ TYPED_TEST(GenericColumnTest, Swap) { EXPECT_TRUE(CompareRecursive(values, *column_B)); } +// GTEST_SKIP for debug builds to draw attention of developer +#if !defined(NDEBUG) +#define COLUMN_DOESNT_IMPLEMENT(comment) GTEST_SKIP() << this->MakeColumn()->GetType().GetName() << " doesn't implement " << comment; +#else +#define COLUMN_DOESNT_IMPLEMENT(comment) GTEST_SUCCEED() << this->MakeColumn()->GetType().GetName() << " doesn't implement " << comment; +#endif + +TYPED_TEST(GenericColumnTest, ReserveAndCapacity) { + if constexpr ( + // TODO(venemkov): test that ColumnType has Reserve() and Capacity() methods + is_one_of_v) { + + auto column = this->MakeColumn(); + EXPECT_EQ(0u, column->Capacity()); + EXPECT_NO_THROW(column->Reserve(100u)); + EXPECT_EQ(100u, column->Capacity()); + EXPECT_EQ(0u, column->Size()); + } + else { + COLUMN_DOESNT_IMPLEMENT("method Reserve() and Capacity()"); + } +} + + +TYPED_TEST(GenericColumnTest, GetWritableData) { + if constexpr ( + // TODO(venemkov): test that ColumnType has GetWritableData() method + is_one_of_v) { + auto [column, values] = this->MakeColumnWithValues(111); + // Do conversion from time_t to internal representation, similar to what ColumnDate and ColumnDate32 do + if constexpr (is_one_of_v) { + std::for_each(values.begin(), values.end(), [](auto & value) { + value /= 86400; + }); + } + + EXPECT_TRUE(CompareRecursive(values, column->GetWritableData())); + } + else { + COLUMN_DOESNT_IMPLEMENT("method GetWritableData()"); + } +} + + TYPED_TEST(GenericColumnTest, LoadAndSave) { auto [column_A, values] = this->MakeColumnWithValues(100); diff --git a/ut/columns_ut.cpp b/ut/columns_ut.cpp index 0de73231..aaad5f26 100644 --- a/ut/columns_ut.cpp +++ b/ut/columns_ut.cpp @@ -965,93 +965,3 @@ TEST(ColumnsCase, ColumnMapT_Wrap) { EXPECT_EQ("123", map_view.At(1)); EXPECT_EQ("abc", map_view.At(2)); } - -TEST(ColumnsCase, ReservedAndCapacity) { - std::vector> columns; - - #define RaC_TEST_CASE(test_id_in, column_type) \ - case test_id_in: { \ - columns.push_back(std::make_shared()); \ - auto column = std::static_pointer_cast(columns[test_id_in]); \ - column->Reserve(100u); \ - ASSERT_EQ(column->Capacity(), 100u); \ - ASSERT_EQ(columns[test_id_in]->Size(), 0u); \ - break; \ - } - - for (uint8_t rac_test_id = 0; rac_test_id < 14; ++rac_test_id) { - switch (rac_test_id) { - RaC_TEST_CASE( 0, ColumnUInt8); - RaC_TEST_CASE( 1, ColumnUInt16); - RaC_TEST_CASE( 2, ColumnUInt32); - RaC_TEST_CASE( 3, ColumnUInt64); - RaC_TEST_CASE( 4, ColumnInt8); - RaC_TEST_CASE( 5, ColumnInt16); - RaC_TEST_CASE( 6, ColumnInt32); - RaC_TEST_CASE( 7, ColumnInt64); - RaC_TEST_CASE( 8, ColumnInt128); - RaC_TEST_CASE( 9, ColumnFloat32); - RaC_TEST_CASE(10, ColumnFloat64); - RaC_TEST_CASE(11, ColumnDate); - RaC_TEST_CASE(12, ColumnDate32); - RaC_TEST_CASE(13, ColumnDateTime); - default: { - EXPECT_NE(0, 0); - break; - } - } - } -} - -TEST(ColumnsCase, RawVector) { - std::vector> columns; - - #define RV_TEST_CASE(test_id_in, column_type) \ - case test_id_in: { \ - columns.push_back(std::make_shared()); \ - auto column = std::static_pointer_cast(columns[test_id_in]); \ - column->Append(10u); \ - column->Append(20u); \ - ASSERT_EQ(columns[test_id_in]->Size(), 2u); \ - auto column_v = column->GetRawVector(); \ - ASSERT_EQ(static_cast(column_v[0]), 10u); \ - ASSERT_EQ(static_cast(column_v[1]), 20u); \ - break; \ - } - - #define RV_TEST_CASE_D(test_id_in, column_type) \ - case test_id_in: { \ - columns.push_back(std::make_shared()); \ - auto column = std::static_pointer_cast(columns[test_id_in]); \ - column->AppendRaw(10u); \ - column->AppendRaw(20u); \ - ASSERT_EQ(columns[test_id_in]->Size(), 2u); \ - auto column_v = column->GetRawVector(); \ - ASSERT_EQ(static_cast(column_v[0]), 10u); \ - ASSERT_EQ(static_cast(column_v[1]), 20u); \ - break; \ - } - - for (uint8_t rv_test_id = 0; rv_test_id < 14; ++rv_test_id) { - switch (rv_test_id) { - RV_TEST_CASE( 0, ColumnUInt8); - RV_TEST_CASE( 1, ColumnUInt16); - RV_TEST_CASE( 2, ColumnUInt32); - RV_TEST_CASE( 3, ColumnUInt64); - RV_TEST_CASE( 4, ColumnInt8); - RV_TEST_CASE( 5, ColumnInt16); - RV_TEST_CASE( 6, ColumnInt32); - RV_TEST_CASE( 7, ColumnInt64); - RV_TEST_CASE( 8, ColumnInt128); - RV_TEST_CASE( 9, ColumnFloat32); - RV_TEST_CASE( 10, ColumnFloat64); - RV_TEST_CASE_D( 11, ColumnDate); - RV_TEST_CASE_D( 12, ColumnDate32); - RV_TEST_CASE_D( 13, ColumnDateTime); - default: { - EXPECT_NE(0, 0); - break; - } - } - } -} diff --git a/ut/utils.h b/ut/utils.h index b4b8e92d..99216743 100644 --- a/ut/utils.h +++ b/ut/utils.h @@ -7,6 +7,7 @@ #include "utils_meta.h" #include "utils_comparison.h" +#include #include #include #include @@ -181,7 +182,7 @@ std::ostream& operator<<(std::ostream & ostr, const PrintContainer& print_con } } - return ostr << "]"; + return ostr << "] (" << std::size(container) << " items)"; } inline uint64_t versionNumber( diff --git a/ut/utils_meta.h b/ut/utils_meta.h index 3c50da4e..6cf55d2e 100644 --- a/ut/utils_meta.h +++ b/ut/utils_meta.h @@ -51,3 +51,18 @@ struct is_instantiation_of< Template, Template > : std::true_type {}; template inline constexpr bool is_string_v = std::is_same_v> || std::is_same_v>; + +// https://stackoverflow.com/a/34111095 +template +struct is_one_of { + static constexpr bool value = false; +}; + +template +struct is_one_of { + static constexpr bool value = + std::is_same::value || is_one_of::value; +}; + +template +inline constexpr bool is_one_of_v = is_one_of::value;