Skip to content

Commit 077fe6f

Browse files
authored
Merge pull request #50 from Enmk/DateTime64
Add DateTime64 data type.
2 parents 4ceb5d1 + 4dd948b commit 077fe6f

File tree

17 files changed

+538
-58
lines changed

17 files changed

+538
-58
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,7 @@ BUCKAROO_DEPS
274274

275275
# Visual Studio Code
276276
/.vscode/
277+
278+
# Vim
279+
*.swp
280+
*.swo

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ C++ client for [Yandex ClickHouse](https://clickhouse.yandex/)
77

88
* Array(T)
99
* Date
10-
* DateTime
10+
* DateTime, DateTime64
1111
* Decimal32, Decimal64, Decimal128
1212
* Enum8, Enum16
1313
* FixedString(N)

clickhouse/columns/date.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,73 @@ ItemView ColumnDateTime::GetItem(size_t index) const {
113113
return data_->GetItem(index);
114114
}
115115

116+
ColumnDateTime64::ColumnDateTime64(size_t precision)
117+
: ColumnDateTime64(Type::CreateDateTime64(precision), std::make_shared<ColumnDecimal>(18ul, precision))
118+
{}
119+
120+
ColumnDateTime64::ColumnDateTime64(TypeRef type, std::shared_ptr<ColumnDecimal> data)
121+
: Column(type),
122+
data_(data),
123+
precision_(type->As<DateTime64Type>()->GetPrecision())
124+
{}
125+
126+
void ColumnDateTime64::Append(const Int64& value) {
127+
// TODO: we need a type, which safely represents datetime.
128+
// The precision of Poco.DateTime is not big enough.
129+
data_->Append(value);
130+
}
131+
132+
//void ColumnDateTime64::Append(const std::string& value) {
133+
// data_->Append(value);
134+
//}
135+
136+
Int64 ColumnDateTime64::At(size_t n) const {
137+
return data_->At(n);
138+
}
139+
140+
void ColumnDateTime64::Append(ColumnRef column) {
141+
if (auto col = column->As<ColumnDateTime64>()) {
142+
data_->Append(col->data_);
143+
}
144+
}
145+
146+
bool ColumnDateTime64::Load(CodedInputStream* input, size_t rows) {
147+
return data_->Load(input, rows);
148+
}
149+
150+
void ColumnDateTime64::Save(CodedOutputStream* output) {
151+
data_->Save(output);
152+
}
153+
154+
void ColumnDateTime64::Clear() {
155+
data_->Clear();
156+
}
157+
size_t ColumnDateTime64::Size() const {
158+
return data_->Size();
159+
}
160+
161+
ItemView ColumnDateTime64::GetItem(size_t index) const {
162+
return data_->GetItem(index);
163+
}
164+
165+
void ColumnDateTime64::Swap(Column& other) {
166+
auto& col = dynamic_cast<ColumnDateTime64&>(other);
167+
if (col.GetPrecision() != GetPrecision()) {
168+
throw std::runtime_error("Can't swap DateTime64 columns when precisions are not the same: "
169+
+ std::to_string(GetPrecision()) + "(this) != " + std::to_string(col.GetPrecision()) + "(that)");
170+
}
171+
172+
data_.swap(col.data_);
173+
}
174+
175+
ColumnRef ColumnDateTime64::Slice(size_t begin, size_t len) {
176+
auto sliced_data = data_->Slice(begin, len)->As<ColumnDecimal>();
177+
178+
return ColumnRef{new ColumnDateTime64(type_, sliced_data)};
179+
}
180+
181+
size_t ColumnDateTime64::GetPrecision() const {
182+
return precision_;
183+
}
184+
116185
}

clickhouse/columns/date.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include "decimal.h"
34
#include "numeric.h"
45

56
#include <ctime>
@@ -82,4 +83,52 @@ class ColumnDateTime : public Column {
8283
std::shared_ptr<ColumnUInt32> data_;
8384
};
8485

86+
87+
/** */
88+
class ColumnDateTime64 : public Column {
89+
public:
90+
explicit ColumnDateTime64(size_t);
91+
92+
/// Appends one element to the end of column.
93+
void Append(const Int64& value);
94+
// It is a bit controversal: users might expect it to parse string of ISO8601 or some other human-friendly format,
95+
// but current implemntation parses it as fractional integer with decimal point, e.g. "123.456".
96+
// void Append(const std::string& value);
97+
98+
/// Returns element at given row number.
99+
Int64 At(size_t n) const;
100+
101+
public:
102+
/// Appends content of given column to the end of current one.
103+
void Append(ColumnRef column) override;
104+
105+
/// Loads column data from input stream.
106+
bool Load(CodedInputStream* input, size_t rows) override;
107+
108+
/// Clear column data .
109+
void Clear() override;
110+
111+
/// Saves column data to output stream.
112+
void Save(CodedOutputStream* output) override;
113+
114+
/// Returns count of rows in the column.
115+
size_t Size() const override;
116+
117+
/// Makes slice of the current column.
118+
ColumnRef Slice(size_t begin, size_t len) override;
119+
120+
void Swap(Column& other) override;
121+
122+
ItemView GetItem(size_t index) const override;
123+
124+
size_t GetPrecision() const;
125+
126+
private:
127+
ColumnDateTime64(TypeRef type, std::shared_ptr<ColumnDecimal> data);
128+
129+
private:
130+
std::shared_ptr<ColumnDecimal> data_;
131+
const size_t precision_;
132+
};
133+
85134
}

clickhouse/columns/decimal.cpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#include "decimal.h"
22

3-
#include <iostream>
4-
53
namespace clickhouse {
64

75
ColumnDecimal::ColumnDecimal(size_t precision, size_t scale)
@@ -16,8 +14,9 @@ ColumnDecimal::ColumnDecimal(size_t precision, size_t scale)
1614
}
1715
}
1816

19-
ColumnDecimal::ColumnDecimal(TypeRef type)
20-
: Column(type)
17+
ColumnDecimal::ColumnDecimal(TypeRef type, ColumnRef data)
18+
: Column(type),
19+
data_(data)
2120
{
2221
}
2322

@@ -83,12 +82,15 @@ void ColumnDecimal::Append(const std::string& value) {
8382
}
8483

8584
Int128 ColumnDecimal::At(size_t i) const {
86-
if (data_->Type()->GetCode() == Type::Int32) {
87-
return static_cast<Int128>(data_->As<ColumnInt32>()->At(i));
88-
} else if (data_->Type()->GetCode() == Type::Int64) {
89-
return static_cast<Int128>(data_->As<ColumnInt64>()->At(i));
90-
} else {
91-
return data_->As<ColumnInt128>()->At(i);
85+
switch (data_->Type()->GetCode()) {
86+
case Type::Int32:
87+
return static_cast<Int128>(data_->As<ColumnInt32>()->At(i));
88+
case Type::Int64:
89+
return static_cast<Int128>(data_->As<ColumnInt64>()->At(i));
90+
case Type::Int128:
91+
return data_->As<ColumnInt128>()->At(i);
92+
default:
93+
throw std::runtime_error("Invalid data_ column type in ColumnDecimal");
9294
}
9395
}
9496

@@ -115,9 +117,8 @@ size_t ColumnDecimal::Size() const {
115117
}
116118

117119
ColumnRef ColumnDecimal::Slice(size_t begin, size_t len) {
118-
std::shared_ptr<ColumnDecimal> slice(new ColumnDecimal(type_));
119-
slice->data_ = data_->Slice(begin, len);
120-
return slice;
120+
// coundn't use std::make_shared since this c-tor is private
121+
return ColumnRef{new ColumnDecimal(type_, data_->Slice(begin, len))};
121122
}
122123

123124
void ColumnDecimal::Swap(Column& other) {
@@ -129,4 +130,14 @@ ItemView ColumnDecimal::GetItem(size_t index) const {
129130
return data_->GetItem(index);
130131
}
131132

133+
size_t ColumnDecimal::GetScale() const
134+
{
135+
return type_->As<DecimalType>()->GetScale();
136+
}
137+
138+
size_t ColumnDecimal::GetPrecision() const
139+
{
140+
return type_->As<DecimalType>()->GetPrecision();
141+
}
142+
132143
}

clickhouse/columns/decimal.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,17 @@ class ColumnDecimal : public Column {
2727
void Swap(Column& other) override;
2828
ItemView GetItem(size_t index) const override;
2929

30+
size_t GetScale() const;
31+
size_t GetPrecision() const;
32+
3033
private:
3134
/// Depending on a precision it can be one of:
3235
/// - ColumnInt32
3336
/// - ColumnInt64
3437
/// - ColumnInt128
3538
ColumnRef data_;
3639

37-
explicit ColumnDecimal(TypeRef type); // for `Slice(…)`
40+
explicit ColumnDecimal(TypeRef type, ColumnRef data);
3841
};
3942

4043
}

clickhouse/columns/factory.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ static ColumnRef CreateTerminalColumn(const TypeAst& ast) {
6565

6666
case Type::DateTime:
6767
return std::make_shared<ColumnDateTime>();
68+
case Type::DateTime64:
69+
return std::make_shared<ColumnDateTime64>(ast.elements.front().value);
6870
case Type::Date:
6971
return std::make_shared<ColumnDate>();
7072

clickhouse/columns/itemview.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ void ItemView::ValidateData(Type::Code type, DataType data) {
2020
ANY, /*String*/
2121
ANY, /*FixedString*/
2222
4, /*DateTime*/
23+
8, /*DateTime64*/
2324
2, /*Date*/
2425
ERR, /*Array*/
2526
ERR, /*Nullable*/

clickhouse/columns/numeric.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,19 @@ ColumnVector<T>::ColumnVector()
1010
}
1111

1212
template <typename T>
13-
ColumnVector<T>::ColumnVector(const std::vector<T>& data)
13+
ColumnVector<T>::ColumnVector(const std::vector<T> & data)
1414
: Column(Type::CreateSimple<T>())
1515
, data_(data)
1616
{
1717
}
1818

19+
template <typename T>
20+
ColumnVector<T>::ColumnVector(std::vector<T> && data)
21+
: Column(Type::CreateSimple<T>())
22+
, data_(std::move(data))
23+
{
24+
}
25+
1926
template <typename T>
2027
void ColumnVector<T>::Append(const T& value) {
2128
data_.push_back(value);

clickhouse/columns/numeric.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class ColumnVector : public Column {
1515
ColumnVector();
1616

1717
explicit ColumnVector(const std::vector<T>& data);
18+
explicit ColumnVector(std::vector<T> && data);
1819

1920
/// Appends one element to the end of column.
2021
void Append(const T& value);
@@ -54,6 +55,7 @@ class ColumnVector : public Column {
5455
};
5556

5657
using Int128 = __int128;
58+
using Int64 = int64_t;
5759

5860
using ColumnUInt8 = ColumnVector<uint8_t>;
5961
using ColumnUInt16 = ColumnVector<uint16_t>;

0 commit comments

Comments
 (0)