|
3 | 3 | #include <clickhouse/columns/date.h> |
4 | 4 | #include <clickhouse/columns/numeric.h> |
5 | 5 | #include <clickhouse/columns/string.h> |
| 6 | +#include <clickhouse/columns/tuple.h> |
6 | 7 | #include <clickhouse/columns/json.h> |
7 | 8 |
|
8 | 9 | #include <gtest/gtest.h> |
@@ -50,6 +51,64 @@ TEST(CreateColumnByType, DateTime) { |
50 | 51 |
|
51 | 52 | ASSERT_EQ(CreateColumnByType("DateTime('UTC')")->As<ColumnDateTime>()->Timezone(), "UTC"); |
52 | 53 | ASSERT_EQ(CreateColumnByType("DateTime64(3, 'UTC')")->As<ColumnDateTime64>()->Timezone(), "UTC"); |
| 54 | + ASSERT_EQ(CreateColumnByType("DateTime('Etc/Can\\'t')")->As<ColumnDateTime>()->Timezone(), "Etc/Can't"); |
| 55 | + ASSERT_EQ(CreateColumnByType("DateTime64(3, 'A\\\\B')")->As<ColumnDateTime64>()->Timezone(), "A\\B"); |
| 56 | +} |
| 57 | + |
| 58 | +TEST(CreateColumnByType, EnumEscapedNames) { |
| 59 | + const std::vector<Type::EnumItem> enum_items = {{"can't", 1}, {"a\\b", 2}, {"a,b=(c)", 3}, {"", 4}}; |
| 60 | + auto col = CreateColumnByType("Enum8('can\\'t' = 1, 'a\\\\b' = 2, 'a,b=(c)' = 3, '' = 4)"); |
| 61 | + ASSERT_NE(nullptr, col); |
| 62 | + ASSERT_TRUE(col->Type()->IsEqual(Type::CreateEnum8(enum_items))); |
| 63 | +} |
| 64 | + |
| 65 | +// Round-trip: build a Type from raw values, render it via GetName() (escape), |
| 66 | +// re-parse the rendered name via CreateColumnByType (unescape) and verify the |
| 67 | +// raw values survive the render->parse cycle. Uses only escape symbols that are |
| 68 | +// currently implemented. |
| 69 | + |
| 70 | +TEST(CreateColumnByType, RoundTrip_Enum) { |
| 71 | + const std::vector<Type::EnumItem> enum_items = {{"can't", 1}, {"a\\b", 2}, {"tab\there", 3}, {"line\nbreak", 4}}; |
| 72 | + auto type = Type::CreateEnum8(enum_items); |
| 73 | + |
| 74 | + auto col = CreateColumnByType(type->GetName()); |
| 75 | + ASSERT_NE(nullptr, col); |
| 76 | + EXPECT_TRUE(col->Type()->IsEqual(type)); |
| 77 | + |
| 78 | + const auto* enum_type = col->Type()->As<EnumType>(); |
| 79 | + ASSERT_NE(nullptr, enum_type); |
| 80 | + EXPECT_EQ(enum_type->GetEnumName(1), "can't"); |
| 81 | + EXPECT_EQ(enum_type->GetEnumValue("a\\b"), 2); |
| 82 | + EXPECT_EQ(enum_type->GetEnumName(3), "tab\there"); |
| 83 | + EXPECT_EQ(enum_type->GetEnumValue("line\nbreak"), 4); |
| 84 | +} |
| 85 | + |
| 86 | +TEST(CreateColumnByType, RoundTrip_DateTime) { |
| 87 | + auto type = Type::CreateDateTime("Etc/Can't"); |
| 88 | + |
| 89 | + auto col = CreateColumnByType(type->GetName()); |
| 90 | + ASSERT_NE(nullptr, col); |
| 91 | + EXPECT_EQ(col->As<ColumnDateTime>()->Timezone(), "Etc/Can't"); |
| 92 | +} |
| 93 | + |
| 94 | +TEST(CreateColumnByType, RoundTrip_DateTime64) { |
| 95 | + auto type = Type::CreateDateTime64(3, "A\\B"); |
| 96 | + |
| 97 | + auto col = CreateColumnByType(type->GetName()); |
| 98 | + ASSERT_NE(nullptr, col); |
| 99 | + EXPECT_EQ(col->As<ColumnDateTime64>()->Timezone(), "A\\B"); |
| 100 | +} |
| 101 | + |
| 102 | +TEST(CreateColumnByType, RoundTrip_Tuple) { |
| 103 | + const std::vector<std::string> item_names = {"a`b", "c.d"}; |
| 104 | + auto type = Type::CreateTuple({Type::CreateSimple<uint8_t>(), Type::CreateString()}, item_names); |
| 105 | + |
| 106 | + auto col = CreateColumnByType(type->GetName()); |
| 107 | + ASSERT_NE(nullptr, col); |
| 108 | + |
| 109 | + const auto* tuple_type = col->Type()->As<TupleType>(); |
| 110 | + ASSERT_NE(nullptr, tuple_type); |
| 111 | + EXPECT_EQ(tuple_type->GetItemNames(), item_names); |
53 | 112 | } |
54 | 113 |
|
55 | 114 | TEST(CreateColumnByType, AggregateFunction) { |
|
0 commit comments