Skip to content

Commit fe037e7

Browse files
committed
Add support for Time/Time64 columns
1 parent 4a278b5 commit fe037e7

18 files changed

Lines changed: 547 additions & 3 deletions

clickhouse/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ SET ( clickhouse-cpp-lib-src
2222
columns/map.cpp
2323
columns/string.cpp
2424
columns/tuple.cpp
25+
columns/time.cpp
2526
columns/uuid.cpp
2627

2728
columns/itemview.cpp
@@ -67,6 +68,7 @@ SET ( clickhouse-cpp-lib-src
6768
columns/nullable.h
6869
columns/numeric.h
6970
columns/string.h
71+
columns/time.h
7072
columns/tuple.h
7173
columns/utils.h
7274
columns/uuid.h
@@ -226,6 +228,7 @@ INSTALL(FILES columns/nullable.h DESTINATION include/clickhouse/columns/)
226228
INSTALL(FILES columns/numeric.h DESTINATION include/clickhouse/columns/)
227229
INSTALL(FILES columns/map.h DESTINATION include/clickhouse/columns/)
228230
INSTALL(FILES columns/string.h DESTINATION include/clickhouse/columns/)
231+
INSTALL(FILES columns/time.h DESTINATION include/clickhouse/columns/)
229232
INSTALL(FILES columns/tuple.h DESTINATION include/clickhouse/columns/)
230233
INSTALL(FILES columns/utils.h DESTINATION include/clickhouse/columns/)
231234
INSTALL(FILES columns/uuid.h DESTINATION include/clickhouse/columns/)

clickhouse/client.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "columns/map.h"
1818
#include "columns/string.h"
1919
#include "columns/tuple.h"
20+
#include "columns/time.h"
2021
#include "columns/uuid.h"
2122

2223
#include <chrono>

clickhouse/columns/factory.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "nullable.h"
1515
#include "numeric.h"
1616
#include "string.h"
17+
#include "./time.h" // `./` avoids possible conflicts with standard C time.h
1718
#include "tuple.h"
1819
#include "uuid.h"
1920

@@ -108,7 +109,6 @@ static ColumnRef CreateTerminalColumn(const TypeAst& ast) {
108109
return std::make_shared<ColumnDate>();
109110
case Type::Date32:
110111
return std::make_shared<ColumnDate32>();
111-
112112
case Type::IPv4:
113113
return std::make_shared<ColumnIPv4>();
114114
case Type::IPv6:
@@ -129,6 +129,13 @@ static ColumnRef CreateTerminalColumn(const TypeAst& ast) {
129129
case Type::MultiPolygon:
130130
return std::make_shared<ColumnMultiPolygon>();
131131

132+
case Type::Time:
133+
return std::make_shared<ColumnTime>();
134+
case Type::Time64:
135+
if (ast.elements.empty()) {
136+
return nullptr;
137+
}
138+
return std::make_shared<ColumnTime64>(GetASTChildElement(ast, 0).value);
132139
default:
133140
return nullptr;
134141
}

clickhouse/columns/itemview.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,15 @@ void ItemView::ValidateData(Type::Code type, DataType data) {
5959
case Type::Code::Date32:
6060
case Type::Code::IPv4:
6161
case Type::Code::Decimal32:
62+
case Type::Code::Time:
6263
return AssertSize({4});
6364

6465
case Type::Code::Int64:
6566
case Type::Code::UInt64:
6667
case Type::Code::Float64:
6768
case Type::Code::DateTime64:
6869
case Type::Code::Decimal64:
70+
case Type::Code::Time64:
6971
return AssertSize({8});
7072

7173
case Type::Code::String:

clickhouse/columns/time.cpp

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#include "time.h"
2+
3+
namespace clickhouse {
4+
5+
ColumnTime::ColumnTime()
6+
: ColumnTime(Type::CreateTime(), std::make_shared<ColumnInt32>()) {}
7+
8+
ColumnTime::ColumnTime(std::vector<int32_t>&& data)
9+
: ColumnTime(Type::CreateTime(), std::make_shared<ColumnInt32>(std::move(data))) {}
10+
11+
ColumnTime::ColumnTime(TypeRef type, std::shared_ptr<ColumnInt32> data)
12+
: Column(std::move(type)),
13+
data_(std::move(data))
14+
{}
15+
16+
void ColumnTime::Append(ValueType value) {
17+
data_->Append(value);
18+
}
19+
20+
ColumnTime::ValueType ColumnTime::At(size_t n) const {
21+
return data_->At(n);
22+
}
23+
24+
std::vector<int32_t>& ColumnTime::GetWritableData() {
25+
return data_->GetWritableData();
26+
}
27+
28+
void ColumnTime::Reserve(size_t new_cap) {
29+
data_->Reserve(new_cap);
30+
}
31+
32+
size_t ColumnTime::Capacity() const {
33+
return data_->Capacity();
34+
}
35+
36+
void ColumnTime::Append(ColumnRef column) {
37+
if (auto col = column->As<ColumnTime>()) {
38+
data_->Append(col->data_);
39+
}
40+
}
41+
42+
bool ColumnTime::LoadBody(InputStream* input, size_t rows) {
43+
return data_->LoadBody(input, rows);
44+
}
45+
46+
void ColumnTime::Clear() {
47+
data_->Clear();
48+
}
49+
50+
void ColumnTime::SaveBody(OutputStream* output) {
51+
data_->SaveBody(output);
52+
}
53+
54+
size_t ColumnTime::Size() const {
55+
return data_->Size();
56+
}
57+
58+
ColumnRef ColumnTime::Slice(size_t begin, size_t len) const {
59+
auto sliced_data = data_->Slice(begin, len)->As<ColumnInt32>();
60+
return ColumnRef{new ColumnTime(type_, sliced_data)};
61+
}
62+
63+
ColumnRef ColumnTime::CloneEmpty() const {
64+
return ColumnRef{new ColumnTime(type_, data_->CloneEmpty()->As<ColumnInt32>())};
65+
}
66+
67+
void ColumnTime::Swap(Column& other) {
68+
auto & col = dynamic_cast<ColumnTime &>(other);
69+
data_.swap(col.data_);
70+
}
71+
72+
ItemView ColumnTime::GetItem(size_t index) const {
73+
return ItemView{Type::Time, data_->GetItem(index)};
74+
}
75+
76+
ColumnTime64::ColumnTime64(size_t precision)
77+
: ColumnTime64(Type::CreateTime64(precision), std::make_shared<ColumnInt64>())
78+
{}
79+
80+
ColumnTime64::ColumnTime64(size_t precision, std::vector<int64_t>&& data)
81+
: ColumnTime64(Type::CreateTime64(precision), std::make_shared<ColumnInt64>(std::move(data)))
82+
{}
83+
84+
ColumnTime64::ColumnTime64(TypeRef type, std::shared_ptr<ColumnInt64> data)
85+
: Column(std::move(type)),
86+
data_(std::move(data)),
87+
precision_{type_->As<Time64Type>()->GetPrecision()}
88+
{}
89+
90+
void ColumnTime64::Append(ValueType value) {
91+
data_->Append(value);
92+
}
93+
94+
ColumnTime64::ValueType ColumnTime64::At(size_t n) const {
95+
return data_->At(n);
96+
}
97+
98+
std::vector<int64_t>& ColumnTime64::GetWritableData() {
99+
return data_->GetWritableData();
100+
}
101+
102+
void ColumnTime64::Reserve(size_t new_cap) {
103+
data_->Reserve(new_cap);
104+
}
105+
106+
size_t ColumnTime64::Capacity() const {
107+
return data_->Capacity();
108+
}
109+
110+
void ColumnTime64::Append(ColumnRef column) {
111+
if (auto col = column->As<ColumnTime64>()) {
112+
data_->Append(col->data_);
113+
}
114+
}
115+
116+
bool ColumnTime64::LoadBody(InputStream* input, size_t rows) {
117+
return data_->LoadBody(input, rows);
118+
}
119+
120+
void ColumnTime64::Clear() {
121+
data_->Clear();
122+
}
123+
124+
void ColumnTime64::SaveBody(OutputStream* output) {
125+
data_->SaveBody(output);
126+
}
127+
128+
size_t ColumnTime64::Size() const {
129+
return data_->Size();
130+
}
131+
132+
ColumnRef ColumnTime64::Slice(size_t begin, size_t len) const {
133+
auto sliced_data = data_->Slice(begin, len)->As<ColumnInt64>();
134+
return ColumnRef{new ColumnTime64(type_, sliced_data)};
135+
}
136+
137+
ColumnRef ColumnTime64::CloneEmpty() const {
138+
return ColumnRef{new ColumnTime64(type_, data_->CloneEmpty()->As<ColumnInt64>())};
139+
}
140+
141+
void ColumnTime64::Swap(Column& other) {
142+
auto & col = dynamic_cast<ColumnTime64 &>(other);
143+
if (col.GetPrecision() != GetPrecision()) {
144+
throw ValidationError("Can't swap Time64 columns when precisions are not the same: "
145+
+ std::to_string(GetPrecision()) + "(this) != "
146+
+ std::to_string(col.GetPrecision()) + "(that)");
147+
}
148+
data_.swap(col.data_);
149+
}
150+
151+
ItemView ColumnTime64::GetItem(size_t index) const {
152+
return ItemView{Type::Time64, data_->GetItem(index)};
153+
}
154+
155+
} // namespace clickhouse

clickhouse/columns/time.h

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#pragma once
2+
3+
#include "column.h"
4+
#include "numeric.h"
5+
6+
namespace clickhouse {
7+
8+
class ColumnTime : public Column {
9+
public:
10+
using ValueType = int32_t;
11+
12+
ColumnTime();
13+
explicit ColumnTime(std::vector<int32_t>&& data);
14+
15+
/// Appends one element to the end of column.
16+
void Append(ValueType value);
17+
18+
/// Returns element at given row number.
19+
ValueType At(size_t n) const;
20+
ValueType operator[](size_t n) const { return At(n); }
21+
22+
/// Get Raw Vector Contents
23+
std::vector<int32_t>& GetWritableData();
24+
25+
public:
26+
/// Increase the capacity of the column for large block insertion.
27+
void Reserve(size_t new_cap) override;
28+
29+
/// Returns the capacity of the column
30+
size_t Capacity() const;
31+
32+
/// Appends content of given column to the end of current one.
33+
void Append(ColumnRef column) override;
34+
35+
/// Loads column data from input stream.
36+
bool LoadBody(InputStream* input, size_t rows) override;
37+
38+
/// Clear column data .
39+
void Clear() override;
40+
41+
/// Saves column data to output stream.
42+
void SaveBody(OutputStream* output) override;
43+
44+
/// Returns count of rows in the column.
45+
size_t Size() const override;
46+
47+
/// Makes slice of the current column.
48+
ColumnRef Slice(size_t begin, size_t len) const override;
49+
ColumnRef CloneEmpty() const override;
50+
void Swap(Column& other) override;
51+
52+
ItemView GetItem(size_t index) const override;
53+
54+
private:
55+
ColumnTime(TypeRef type, std::shared_ptr<ColumnInt32> data);
56+
57+
private:
58+
std::shared_ptr<ColumnInt32> data_;
59+
};
60+
61+
class ColumnTime64 : public Column {
62+
public:
63+
using ValueType = int64_t;
64+
65+
explicit ColumnTime64(size_t precision);
66+
ColumnTime64(size_t precision, std::vector<int64_t>&& data);
67+
68+
/// Appends one element to the end of column.
69+
void Append(ValueType value);
70+
71+
/// Returns element at given row number.
72+
ValueType At(size_t n) const;
73+
74+
ValueType operator[](size_t n) const { return At(n); }
75+
76+
/// Get Raw Vector Contents
77+
std::vector<int64_t>& GetWritableData();
78+
79+
public:
80+
/// Increase the capacity of the column for large block insertion.
81+
void Reserve(size_t new_cap) override;
82+
83+
/// Returns the capacity of the column
84+
size_t Capacity() const;
85+
86+
/// Appends content of given column to the end of current one.
87+
void Append(ColumnRef column) override;
88+
89+
/// Loads column data from input stream.
90+
bool LoadBody(InputStream* input, size_t rows) override;
91+
92+
/// Clear column data .
93+
void Clear() override;
94+
95+
/// Saves column data to output stream.
96+
void SaveBody(OutputStream* output) override;
97+
98+
/// Returns count of rows in the column.
99+
size_t Size() const override;
100+
101+
/// Makes slice of the current column.
102+
ColumnRef Slice(size_t begin, size_t len) const override;
103+
ColumnRef CloneEmpty() const override;
104+
void Swap(Column& other) override;
105+
106+
ItemView GetItem(size_t index) const override;
107+
108+
size_t GetPrecision() const { return precision_; };
109+
110+
private:
111+
ColumnTime64(TypeRef type, std::shared_ptr<ColumnInt64> data);
112+
113+
private:
114+
std::shared_ptr<ColumnInt64> data_;
115+
const size_t precision_;
116+
};
117+
118+
}

clickhouse/types/type_parser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ static const std::unordered_map<std::string, Type::Code> kTypeCode = {
6565
{ "Ring", Type::Ring },
6666
{ "Polygon", Type::Polygon },
6767
{ "MultiPolygon", Type::MultiPolygon },
68+
{ "Time", Type::Time },
69+
{ "Time64", Type::Time64 },
6870
};
6971

7072
template <typename L, typename R>

0 commit comments

Comments
 (0)