Skip to content

Commit 8b464b5

Browse files
committed
Merge remote-tracking branch 'extras/master' into sync_projects
2 parents 3d7f9ca + ca6c4af commit 8b464b5

21 files changed

+575
-232
lines changed

.clang-format

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Language: Cpp
2+
BasedOnStyle: Google
3+
4+
AccessModifierOffset: -4
5+
AlignConsecutiveAssignments: true
6+
AllowShortFunctionsOnASingleLine: InlineOnly
7+
ColumnLimit: 140
8+
DerivePointerAlignment: false
9+
FixNamespaceComments: true
10+
IndentWidth: 4
11+
PointerAlignment: Left

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -271,3 +271,6 @@ __pycache__/
271271
/buckaroo/
272272
.buckconfig.local
273273
BUCKAROO_DEPS
274+
275+
# Visual Studio Code
276+
/.vscode/

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ C++ client for [Yandex ClickHouse](https://clickhouse.yandex/)
88
* Array(T)
99
* Date
1010
* DateTime
11+
* Decimal32, Decimal64, Decimal128
1112
* Enum8, Enum16
1213
* FixedString(N)
1314
* Float32, Float64

clickhouse/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ SET ( clickhouse-cpp-lib-src
88

99
columns/array.cpp
1010
columns/date.cpp
11+
columns/decimal.cpp
1112
columns/enum.cpp
1213
columns/factory.cpp
1314
columns/nullable.cpp

clickhouse/client.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ Client::Impl::Impl(const ClientOptions& opts)
165165
, buffered_output_(&socket_output_)
166166
, output_(&buffered_output_)
167167
{
168+
// TODO: throw on big-endianness of platform
169+
168170
for (int i = 0; ; ) {
169171
try {
170172
ResetConnection();

clickhouse/client.h

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "columns/array.h"
77
#include "columns/date.h"
8+
#include "columns/decimal.h"
89
#include "columns/enum.h"
910
#include "columns/nullable.h"
1011
#include "columns/numeric.h"

clickhouse/columns/column.h

+8-13
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

3-
#include "../base/input.h"
43
#include "../base/coded.h"
4+
#include "../base/input.h"
55
#include "../types/types.h"
66

77
namespace clickhouse {
@@ -11,24 +11,19 @@ using ColumnRef = std::shared_ptr<class Column>;
1111
/**
1212
* An abstract base of all columns classes.
1313
*/
14-
class Column : public std::enable_shared_from_this<Column>
15-
{
14+
class Column : public std::enable_shared_from_this<Column> {
1615
public:
17-
explicit inline Column(TypeRef type)
18-
: type_(type)
19-
{
20-
}
16+
explicit inline Column(TypeRef type) : type_(type) {}
2117

22-
virtual ~Column()
23-
{ }
18+
virtual ~Column() {}
2419

25-
/// Downcast pointer to the specific culumn's subtype.
20+
/// Downcast pointer to the specific column's subtype.
2621
template <typename T>
2722
inline std::shared_ptr<T> As() {
2823
return std::dynamic_pointer_cast<T>(shared_from_this());
2924
}
3025

31-
/// Downcast pointer to the specific culumn's subtype.
26+
/// Downcast pointer to the specific column's subtype.
3227
template <typename T>
3328
inline std::shared_ptr<const T> As() const {
3429
return std::dynamic_pointer_cast<const T>(shared_from_this());
@@ -45,7 +40,7 @@ class Column : public std::enable_shared_from_this<Column>
4540

4641
/// Saves column data to output stream.
4742
virtual void Save(CodedOutputStream* output) = 0;
48-
43+
4944
/// Clear column data .
5045
virtual void Clear() = 0;
5146

@@ -59,4 +54,4 @@ class Column : public std::enable_shared_from_this<Column>
5954
TypeRef type_;
6055
};
6156

62-
}
57+
} // namespace clickhouse

clickhouse/columns/decimal.cpp

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#include "decimal.h"
2+
3+
#include "numeric.h"
4+
5+
namespace clickhouse {
6+
7+
ColumnDecimal::ColumnDecimal(size_t precision, size_t scale) : Column(Type::CreateDecimal(precision, scale)) {
8+
if (precision <= 9) {
9+
data_ = ColumnRef(new ColumnInt32());
10+
} else if (precision <= 18) {
11+
data_ = ColumnRef(new ColumnInt64());
12+
} else {
13+
data_ = ColumnRef(new ColumnInt128());
14+
}
15+
}
16+
17+
void ColumnDecimal::Append(const Int128& value) {
18+
if (data_->Type()->GetCode() == Type::Int32) {
19+
data_->As<ColumnInt32>()->Append(static_cast<ColumnInt32::DataType>(value));
20+
} else if (data_->Type()->GetCode() == Type::Int64) {
21+
data_->As<ColumnInt64>()->Append(static_cast<ColumnInt64::DataType>(value));
22+
} else {
23+
data_->As<ColumnInt128>()->Append(static_cast<ColumnInt128::DataType>(value));
24+
}
25+
}
26+
27+
void ColumnDecimal::Append(const std::string &value) {
28+
Int128 int_value = 0;
29+
auto c = value.begin();
30+
bool sign = true;
31+
32+
while (c != value.end()) {
33+
if (*c == '-') {
34+
sign = false;
35+
if (c != value.begin()) {
36+
break;
37+
}
38+
} else if (*c == '.') {
39+
// TODO: compare distance with `scale`
40+
} else if (*c >= '0' && *c <= '9') {
41+
int_value = int_value * 10 + (*c - '0');
42+
} else {
43+
// TODO: throw exception on unexpected symbol
44+
}
45+
++c;
46+
}
47+
48+
if (c != value.end()) {
49+
// TODO: throw exception about symbols after 'minus'
50+
}
51+
52+
Append(sign ? int_value : -int_value);
53+
}
54+
55+
Int128 ColumnDecimal::At(size_t i) const {
56+
if (data_->Type()->GetCode() == Type::Int32) {
57+
return static_cast<Int128>(data_->As<ColumnInt32>()->At(i));
58+
} else if (data_->Type()->GetCode() == Type::Int64) {
59+
return static_cast<Int128>(data_->As<ColumnInt64>()->At(i));
60+
} else {
61+
return data_->As<ColumnInt128>()->At(i);
62+
}
63+
}
64+
65+
ColumnRef ColumnDecimal::Slice(size_t begin, size_t len) {
66+
std::shared_ptr<ColumnDecimal> slice(new ColumnDecimal(Type()));
67+
slice->data_ = data_->Slice(begin, len);
68+
return slice;
69+
}
70+
71+
ColumnDecimal::ColumnDecimal(TypeRef type) : Column(type) {
72+
}
73+
74+
} // namespace clickhouse

clickhouse/columns/decimal.h

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#pragma once
2+
3+
#include "column.h"
4+
5+
namespace clickhouse {
6+
7+
using Int128 = __int128;
8+
9+
/**
10+
* Represents a column of decimal type.
11+
*/
12+
13+
class ColumnDecimal : public Column {
14+
public:
15+
ColumnDecimal(size_t precision, size_t scale);
16+
17+
void Append(const Int128& value);
18+
void Append(const std::string& value);
19+
20+
Int128 At(size_t i) const;
21+
22+
public:
23+
void Append(ColumnRef column) override { data_->Append(column); }
24+
bool Load(CodedInputStream* input, size_t rows) override { return data_->Load(input, rows); }
25+
void Save(CodedOutputStream* output) override { data_->Save(output); }
26+
void Clear() override { data_->Clear(); }
27+
size_t Size() const override { return data_->Size(); }
28+
ColumnRef Slice(size_t begin, size_t len) override;
29+
30+
private:
31+
/// Depending on a precision it can be one of:
32+
/// - ColumnInt32
33+
/// - ColumnInt64
34+
/// - ColumnInt128
35+
ColumnRef data_;
36+
37+
explicit ColumnDecimal(TypeRef type); // for `Slice(…)`
38+
};
39+
40+
} // namespace clickhouse

clickhouse/columns/enum.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ ColumnEnum<T>::ColumnEnum(TypeRef type, const std::vector<T>& data)
1919
template <typename T>
2020
void ColumnEnum<T>::Append(const T& value, bool checkValue) {
2121
if (checkValue) {
22-
// TODO type_->HasEnumValue(value), "Enum type doesn't have value " + std::to_string(value);
22+
// TODO: type_->HasEnumValue(value), "Enum type doesn't have value " + std::to_string(value);
2323
}
2424
data_.push_back(value);
2525
}
2626

2727
template <typename T>
2828
void ColumnEnum<T>::Append(const std::string& name) {
29-
data_.push_back(EnumType(type_).GetEnumValue(name));
29+
data_.push_back(type_->As<EnumType>()->GetEnumValue(name));
3030
}
3131

3232
template <typename T>
@@ -41,7 +41,7 @@ const T& ColumnEnum<T>::At(size_t n) const {
4141

4242
template <typename T>
4343
const std::string ColumnEnum<T>::NameAt(size_t n) const {
44-
return EnumType(type_).GetEnumName(data_.at(n));
44+
return type_->As<EnumType>()->GetEnumName(data_.at(n));
4545
}
4646

4747
template <typename T>
@@ -59,7 +59,7 @@ void ColumnEnum<T>::SetAt(size_t n, const T& value, bool checkValue) {
5959

6060
template <typename T>
6161
void ColumnEnum<T>::SetNameAt(size_t n, const std::string& name) {
62-
data_.at(n) = EnumType(type_).GetEnumValue(name);
62+
data_.at(n) = type_->As<EnumType>()->GetEnumValue(name);
6363
}
6464

6565
template <typename T>

clickhouse/columns/factory.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "array.h"
44
#include "date.h"
5+
#include "decimal.h"
56
#include "enum.h"
67
#include "nullable.h"
78
#include "numeric.h"
@@ -52,6 +53,17 @@ static ColumnRef CreateTerminalColumn(const TypeAst& ast) {
5253
case Type::Date:
5354
return std::make_shared<ColumnDate>();
5455

56+
case Type::Decimal32:
57+
return std::make_shared<ColumnDecimal>(9, ast.elements.front().value);
58+
case Type::Decimal64:
59+
return std::make_shared<ColumnDecimal>(18, ast.elements.front().value);
60+
case Type::Decimal128:
61+
if (ast.elements.size() == 2) {
62+
return std::make_shared<ColumnDecimal>(ast.elements.front().value, ast.elements.back().value);
63+
} else if (ast.elements.size() == 1) {
64+
return std::make_shared<ColumnDecimal>(38, ast.elements.front().value);
65+
}
66+
5567
default:
5668
return nullptr;
5769
}

clickhouse/columns/numeric.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ template class ColumnVector<int8_t>;
6969
template class ColumnVector<int16_t>;
7070
template class ColumnVector<int32_t>;
7171
template class ColumnVector<int64_t>;
72+
template class ColumnVector<__int128>;
7273

7374
template class ColumnVector<uint8_t>;
7475
template class ColumnVector<uint16_t>;

clickhouse/columns/numeric.h

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ namespace clickhouse {
1010
template <typename T>
1111
class ColumnVector : public Column {
1212
public:
13+
using DataType = T;
14+
1315
ColumnVector();
1416

1517
explicit ColumnVector(const std::vector<T>& data);
@@ -55,6 +57,7 @@ using ColumnInt8 = ColumnVector<int8_t>;
5557
using ColumnInt16 = ColumnVector<int16_t>;
5658
using ColumnInt32 = ColumnVector<int32_t>;
5759
using ColumnInt64 = ColumnVector<int64_t>;
60+
using ColumnInt128 = ColumnVector<__int128>;
5861

5962
using ColumnFloat32 = ColumnVector<float>;
6063
using ColumnFloat64 = ColumnVector<double>;

clickhouse/types/type_parser.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ static const std::unordered_map<std::string, Type::Code> kTypeCode = {
2828
{ "Enum8", Type::Enum8 },
2929
{ "Enum16", Type::Enum16 },
3030
{ "UUID", Type::UUID },
31+
{ "Decimal32", Type::Decimal32 },
32+
{ "Decimal64", Type::Decimal64 },
33+
{ "Decimal128", Type::Decimal128 },
34+
{ "Decimal", Type::Decimal128 },
3135
};
3236

3337
static Type::Code GetTypeCode(const std::string& name) {

clickhouse/types/type_parser.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct TypeAst {
1717
Number,
1818
Terminal,
1919
Tuple,
20-
Enum
20+
Enum,
2121
};
2222

2323
/// Type's category.

0 commit comments

Comments
 (0)