@@ -30,7 +30,29 @@ class ClientCase : public testing::TestWithParam<ClientOptions> {
30
30
client_->Execute (" DROP DATABASE test_clickhouse_cpp" );
31
31
}
32
32
33
+ template <typename T>
34
+ std::shared_ptr<T> createTableWithOneColumn (Block & block)
35
+ {
36
+ auto col = std::make_shared<T>();
37
+ const auto type_name = col->GetType ().GetName ();
38
+
39
+ client_->Execute (" DROP TABLE IF EXISTS " + table_name + " ;" );
40
+ client_->Execute (" CREATE TABLE IF NOT EXISTS " + table_name + " ( " + column_name + " " + type_name + " )"
41
+ " ENGINE = Memory" );
42
+
43
+ block.AppendColumn (" test_column" , col);
44
+
45
+ return col;
46
+ }
47
+
48
+ std::string getOneColumnSelectQuery () const
49
+ {
50
+ return " SELECT " + column_name + " FROM " + table_name;
51
+ }
52
+
33
53
std::unique_ptr<Client> client_;
54
+ const std::string table_name = " test_clickhouse_cpp.test_ut_table" ;
55
+ const std::string column_name = " test_column" ;
34
56
};
35
57
36
58
TEST_P (ClientCase, Array) {
@@ -117,22 +139,57 @@ TEST_P(ClientCase, Date) {
117
139
118
140
TEST_P (ClientCase, LowCardinality) {
119
141
Block block;
120
- client_-> Execute ( " DROP TABLE IF EXISTS test_clickhouse_cpp.low_cardinality; " );
142
+ auto lc = createTableWithOneColumn<ColumnLowCardinalityT<ColumnString>>(block );
121
143
122
- client_->Execute (" CREATE TABLE IF NOT EXISTS "
123
- " test_clickhouse_cpp.low_cardinality (lc LowCardinality(String)) "
124
- " ENGINE = Memory" );
144
+ const std::vector<std::string> data{{" FooBar" , " 1" , " 2" , " Foo" , " 4" , " Bar" , " Foo" , " 7" , " 8" , " Foo" }};
145
+ lc->AppendMany (data);
146
+
147
+ block.RefreshRowCount ();
148
+ client_->Insert (table_name, block);
149
+
150
+ size_t total_rows = 0 ;
151
+ client_->Select (getOneColumnSelectQuery (),
152
+ [&total_rows, &data](const Block& block) {
153
+ total_rows += block.GetRowCount ();
154
+ if (block.GetRowCount () == 0 ) {
155
+ return ;
156
+ }
157
+
158
+ ASSERT_EQ (1U , block.GetColumnCount ());
159
+ if (auto col = block[0 ]->As <ColumnLowCardinalityT<ColumnString>>()) {
160
+ ASSERT_EQ (data.size (), col->Size ());
161
+ for (size_t i = 0 ; i < col->Size (); ++i) {
162
+ EXPECT_EQ (data[i], (*col)[i]) << " at index: " << i;
163
+ }
164
+ }
165
+ }
166
+ );
167
+
168
+ ASSERT_EQ (total_rows, data.size ());
169
+ }
170
+
171
+ TEST_P (ClientCase, LowCardinality_InsertAfterClear) {
172
+ // User can successfully insert values after invoking Clear() on LC column.
173
+ Block block;
174
+ auto lc = createTableWithOneColumn<ColumnLowCardinalityT<ColumnString>>(block);
175
+
176
+ // Add some data, but don't care about it much.
177
+ lc->AppendMany (std::vector<std::string_view>{" abc" , " def" , " 123" , " abc" , " 123" , " def" , " ghi" });
178
+ EXPECT_GT (lc->Size (), 0u );
179
+ EXPECT_GT (lc->GetDictionarySize (), 0u );
125
180
126
- auto lc = std::make_shared<ColumnLowCardinalityT<ColumnString>> ();
181
+ lc-> Clear ();
127
182
183
+ // Now ensure that all data appended after Clear() is inserted properly
128
184
const std::vector<std::string> data{{" FooBar" , " 1" , " 2" , " Foo" , " 4" , " Bar" , " Foo" , " 7" , " 8" , " Foo" }};
129
185
lc->AppendMany (data);
130
186
131
- block.AppendColumn ( " lc " , lc );
132
- client_->Insert (" test_clickhouse_cpp.low_cardinality " , block);
187
+ block.RefreshRowCount ( );
188
+ client_->Insert (table_name , block);
133
189
190
+ // Now validate that data was properly inserted
134
191
size_t total_rows = 0 ;
135
- client_->Select (" SELECT lc FROM test_clickhouse_cpp.low_cardinality " ,
192
+ client_->Select (getOneColumnSelectQuery () ,
136
193
[&total_rows, &data](const Block& block) {
137
194
total_rows += block.GetRowCount ();
138
195
if (block.GetRowCount () == 0 ) {
0 commit comments