Skip to content

Commit 2cdb0d8

Browse files
authored
Merge pull request ClickHouse#45 from Enmk/SimpleAggregateFunction
Implemented reading values of SimpleAggregateFunction
2 parents 69470d1 + 76c0890 commit 2cdb0d8

File tree

8 files changed

+123
-10
lines changed

8 files changed

+123
-10
lines changed

clickhouse/client.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,6 @@ struct ClientInfo {
5555
uint32_t client_revision = 0;
5656
};
5757

58-
struct ServerInfo {
59-
std::string name;
60-
std::string timezone;
61-
std::string display_name;
62-
uint64_t version_major;
63-
uint64_t version_minor;
64-
uint64_t version_patch;
65-
uint64_t revision;
66-
};
67-
6858
std::ostream& operator<<(std::ostream& os, const ClientOptions& opt) {
6959
os << "Client(" << opt.user << '@' << opt.host << ":" << opt.port
7060
<< " ping_before_query:" << opt.ping_before_query
@@ -91,6 +81,8 @@ class Client::Impl {
9181

9282
void ResetConnection();
9383

84+
const ServerInfo& GetServerInfo() const;
85+
9486
private:
9587
bool Handshake();
9688

@@ -297,6 +289,10 @@ void Client::Impl::ResetConnection() {
297289
}
298290
}
299291

292+
const ServerInfo& Client::Impl::GetServerInfo() const {
293+
return server_info_;
294+
}
295+
300296
bool Client::Impl::Handshake() {
301297
if (!SendHello()) {
302298
return false;
@@ -789,4 +785,8 @@ void Client::ResetConnection() {
789785
impl_->ResetConnection();
790786
}
791787

788+
const ServerInfo& Client::GetServerInfo() const {
789+
return impl_->GetServerInfo();
790+
}
791+
792792
}

clickhouse/client.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@
2323

2424
namespace clickhouse {
2525

26+
struct ServerInfo {
27+
std::string name;
28+
std::string timezone;
29+
std::string display_name;
30+
uint64_t version_major;
31+
uint64_t version_minor;
32+
uint64_t version_patch;
33+
uint64_t revision;
34+
};
35+
2636
/// Methods of block compression.
2737
enum class CompressionMethod {
2838
None = -1,
@@ -106,6 +116,8 @@ class Client {
106116
/// Reset connection with initial params.
107117
void ResetConnection();
108118

119+
const ServerInfo& GetServerInfo() const;
120+
109121
private:
110122
ClientOptions options_;
111123

clickhouse/columns/factory.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ static ColumnRef CreateColumnFromAst(const TypeAst& ast) {
147147
throw std::runtime_error("LowCardinality(" + nested.name + ") is not supported");
148148
}
149149
}
150+
case TypeAst::SimpleAggregateFunction: {
151+
return CreateTerminalColumn(ast.elements.back());
152+
}
150153

151154
case TypeAst::Null:
152155
case TypeAst::Number:

clickhouse/types/type_parser.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ static TypeAst::Meta GetTypeMeta(const StringView& name) {
7979
return TypeAst::LowCardinality;
8080
}
8181

82+
if (name == "SimpleAggregateFunction") {
83+
return TypeAst::SimpleAggregateFunction;
84+
}
85+
8286
return TypeAst::Terminal;
8387
}
8488

@@ -135,7 +139,12 @@ bool TypeParser::Parse(TypeAst* type) {
135139
type_ = &type_->elements.back();
136140
break;
137141
case Token::EOS:
142+
{
143+
// Ubalanced braces, brackets, etc is an error.
144+
if (open_elements_.size() != 1)
145+
return false;
138146
return true;
147+
}
139148
case Token::Invalid:
140149
return false;
141150
}

clickhouse/types/type_parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct TypeAst {
1919
Tuple,
2020
Enum,
2121
LowCardinality,
22+
SimpleAggregateFunction
2223
};
2324

2425
/// Type's category.

ut/client_ut.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33

44
using namespace clickhouse;
55

6+
namespace clickhouse
7+
{
8+
std::ostream & operator<<(std::ostream & ostr, const ServerInfo & server_info)
9+
{
10+
return ostr << server_info.name << "/" << server_info.display_name
11+
<< " ver "
12+
<< server_info.version_major << "."
13+
<< server_info.version_minor << "."
14+
<< server_info.version_patch
15+
<< " (" << server_info.revision << ")";
16+
}
17+
}
18+
619
// Use value-parameterized tests to run same tests with different client
720
// options.
821
class ClientCase : public testing::TestWithParam<ClientOptions> {
@@ -284,6 +297,40 @@ TEST_P(ClientCase, Numbers) {
284297
EXPECT_EQ(100000U, num);
285298
}
286299

300+
TEST_P(ClientCase, SimpleAggregateFunction) {
301+
const auto & server_info = client_->GetServerInfo();
302+
if (server_info.version_major <= 19 && server_info.version_minor < 9) {
303+
std::cout << "Test is skipped since server '" << server_info << "' does not support SimpleAggregateFunction" << std::endl;
304+
return;
305+
}
306+
307+
client_->Execute("DROP TABLE IF EXISTS test_clickhouse_cpp.SimpleAggregateFunction");
308+
client_->Execute(
309+
"CREATE TABLE IF NOT EXISTS test_clickhouse_cpp.SimpleAggregateFunction (saf SimpleAggregateFunction(sum, UInt64))"
310+
"ENGINE = Memory");
311+
312+
constexpr size_t EXPECTED_ROWS = 10;
313+
client_->Execute("INSERT INTO test_clickhouse_cpp.SimpleAggregateFunction (saf) SELECT number FROM system.numbers LIMIT 10");
314+
315+
size_t total_rows = 0;
316+
client_->Select("Select * FROM test_clickhouse_cpp.SimpleAggregateFunction", [&total_rows](const Block & block) {
317+
if (block.GetRowCount() == 0)
318+
return;
319+
320+
total_rows += block.GetRowCount();
321+
auto col = block[0]->As<ColumnUInt64>();
322+
ASSERT_NE(nullptr, col);
323+
324+
for (size_t r = 0; r < col->Size(); ++r) {
325+
EXPECT_EQ(r, col->At(r));
326+
}
327+
328+
EXPECT_EQ(total_rows, col->Size());
329+
});
330+
331+
EXPECT_EQ(EXPECTED_ROWS, total_rows);
332+
}
333+
287334
TEST_P(ClientCase, Cancellable) {
288335
/// Create a table.
289336
client_->Execute(

ut/columns_ut.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <clickhouse/columns/array.h>
22
#include <clickhouse/columns/date.h>
33
#include <clickhouse/columns/enum.h>
4+
#include <clickhouse/columns/factory.h>
45
#include <clickhouse/columns/lowcardinality.h>
56
#include <clickhouse/columns/nullable.h>
67
#include <clickhouse/columns/numeric.h>
@@ -258,3 +259,26 @@ TEST(ColumnsCase, LowCardinalityString_Save) {
258259
EXPECT_EQ(col.At(i), foobar(i)) << " at pos: " << i;
259260
}
260261
}
262+
263+
TEST(ColumnsCase, CreateSimpleAggregateFunction) {
264+
auto col = CreateColumnByType("SimpleAggregateFunction(funt, Int32)");
265+
266+
ASSERT_EQ("Int32", col->Type()->GetName());
267+
ASSERT_EQ(Type::Int32, col->Type()->GetCode());
268+
ASSERT_NE(nullptr, col->As<ColumnInt32>());
269+
}
270+
271+
272+
TEST(CreateColumnByType, UnmatchedBrackets) {
273+
// When type string has unmatched brackets, CreateColumnByType must return nullptr.
274+
ASSERT_EQ(nullptr, CreateColumnByType("FixedString(10"));
275+
ASSERT_EQ(nullptr, CreateColumnByType("Nullable(FixedString(10000"));
276+
ASSERT_EQ(nullptr, CreateColumnByType("Nullable(FixedString(10000)"));
277+
ASSERT_EQ(nullptr, CreateColumnByType("LowCardinality(Nullable(FixedString(10000"));
278+
ASSERT_EQ(nullptr, CreateColumnByType("LowCardinality(Nullable(FixedString(10000)"));
279+
ASSERT_EQ(nullptr, CreateColumnByType("LowCardinality(Nullable(FixedString(10000))"));
280+
ASSERT_EQ(nullptr, CreateColumnByType("Array(LowCardinality(Nullable(FixedString(10000"));
281+
ASSERT_EQ(nullptr, CreateColumnByType("Array(LowCardinality(Nullable(FixedString(10000)"));
282+
ASSERT_EQ(nullptr, CreateColumnByType("Array(LowCardinality(Nullable(FixedString(10000))"));
283+
ASSERT_EQ(nullptr, CreateColumnByType("Array(LowCardinality(Nullable(FixedString(10000)))"));
284+
}

ut/type_parser_ut.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,20 @@ TEST(TypeParserCase, LowCardinality_FixedString) {
190190
auto param = TypeAst{TypeAst::Number, Type::Void, "", 10, {}};
191191
ASSERT_EQ(ast.elements[0].elements[0], param);
192192
}
193+
194+
TEST(TypeParserCase, SimpleAggregateFunction_UInt64) {
195+
TypeAst ast;
196+
TypeParser("SimpleAggregateFunction(func, UInt64)").Parse(&ast);
197+
ASSERT_EQ(ast.meta, TypeAst::SimpleAggregateFunction);
198+
ASSERT_EQ(ast.name, "SimpleAggregateFunction");
199+
ASSERT_EQ(ast.code, Type::Void);
200+
ASSERT_EQ(ast.elements.size(), 2u);
201+
ASSERT_EQ(ast.elements[0].name, "func");
202+
ASSERT_EQ(ast.elements[0].code, Type::Void);
203+
ASSERT_EQ(ast.elements[0].meta, TypeAst::Terminal);
204+
ASSERT_EQ(ast.elements[0].value, 0);
205+
ASSERT_EQ(ast.elements[1].name, "UInt64");
206+
ASSERT_EQ(ast.elements[1].code, Type::UInt64);
207+
ASSERT_EQ(ast.elements[1].meta, TypeAst::Terminal);
208+
ASSERT_EQ(ast.elements[1].value, 0);
209+
}

0 commit comments

Comments
 (0)