Skip to content

Support UInt128 type #424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ C++ client for [ClickHouse](https://clickhouse.com/).
* LowCardinality(String) or LowCardinality(FixedString(N))
* Tuple
* UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64
* Int128
* UInt128, Int128
* UUID
* Map
* Point, Ring, Polygon, MultiPolygon
Expand Down
4 changes: 1 addition & 3 deletions clickhouse/base/uuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

namespace clickhouse {

using UInt128 = std::pair<uint64_t, uint64_t>;

using UUID = UInt128;
using UUID = std::pair<uint64_t, uint64_t>;

}
2 changes: 2 additions & 0 deletions clickhouse/columns/factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ static ColumnRef CreateTerminalColumn(const TypeAst& ast) {
return std::make_shared<ColumnInt64>();
case Type::Int128:
return std::make_shared<ColumnInt128>();
case Type::UInt128:
return std::make_shared<ColumnUInt128>();

case Type::Float32:
return std::make_shared<ColumnFloat32>();
Expand Down
1 change: 1 addition & 0 deletions clickhouse/columns/itemview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ void ItemView::ValidateData(Type::Code type, DataType data) {

case Type::Code::IPv6:
case Type::Code::UUID:
case Type::Code::UInt128:
case Type::Code::Int128:
case Type::Code::Decimal128:
return AssertSize({16});
Expand Down
2 changes: 1 addition & 1 deletion clickhouse/columns/itemview.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct ItemView {
inline auto ConvertToStorageValue(const T& t) {
if constexpr (std::is_same_v<std::string_view, T> || std::is_same_v<std::string, T>) {
return std::string_view{t};
} else if constexpr (std::is_fundamental_v<T> || std::is_same_v<Int128, std::decay_t<T>>) {
} else if constexpr (std::is_fundamental_v<T> || std::is_same_v<Int128, std::decay_t<T>> || std::is_same_v<UInt128, std::decay_t<T>>) {
return std::string_view{reinterpret_cast<const char*>(&t), sizeof(T)};
} else {
static_assert(!std::is_same_v<T, T>, "Unknown type, which can't be stored in ItemView");
Expand Down
1 change: 1 addition & 0 deletions clickhouse/columns/numeric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ template class ColumnVector<uint16_t>;
template class ColumnVector<uint32_t>;
template class ColumnVector<uint64_t>;
template class ColumnVector<Int128>;
template class ColumnVector<UInt128>;

template class ColumnVector<float>;
template class ColumnVector<double>;
Expand Down
2 changes: 2 additions & 0 deletions clickhouse/columns/numeric.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@ class ColumnVector : public Column {
};

using Int128 = absl::int128;
using UInt128 = absl::uint128;
using Int64 = int64_t;

using ColumnUInt8 = ColumnVector<uint8_t>;
using ColumnUInt16 = ColumnVector<uint16_t>;
using ColumnUInt32 = ColumnVector<uint32_t>;
using ColumnUInt64 = ColumnVector<uint64_t>;
using ColumnUInt128 = ColumnVector<UInt128>;

using ColumnInt8 = ColumnVector<int8_t>;
using ColumnInt16 = ColumnVector<int16_t>;
Expand Down
2 changes: 1 addition & 1 deletion clickhouse/types/type_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ static const std::unordered_map<std::string, Type::Code> kTypeCode = {
{ "IPv4", Type::IPv4 },
{ "IPv6", Type::IPv6 },
{ "Int128", Type::Int128 },
// { "UInt128", Type::UInt128 },
{ "UInt128", Type::UInt128 },
{ "Decimal", Type::Decimal },
{ "Decimal32", Type::Decimal32 },
{ "Decimal64", Type::Decimal64 },
Expand Down
3 changes: 3 additions & 0 deletions clickhouse/types/types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const char* Type::TypeName(Type::Code code) {
case Type::Code::IPv4: return "IPv4";
case Type::Code::IPv6: return "IPv6";
case Type::Code::Int128: return "Int128";
case Type::Code::UInt128: return "UInt128";
case Type::Code::Decimal: return "Decimal";
case Type::Code::Decimal32: return "Decimal32";
case Type::Code::Decimal64: return "Decimal64";
Expand Down Expand Up @@ -68,6 +69,7 @@ std::string Type::GetName() const {
case UInt16:
case UInt32:
case UInt64:
case UInt128:
case UUID:
case Float32:
case Float64:
Expand Down Expand Up @@ -126,6 +128,7 @@ uint64_t Type::GetTypeUniqueId() const {
case UInt16:
case UInt32:
case UInt64:
case UInt128:
case UUID:
case Float32:
case Float64:
Expand Down
7 changes: 7 additions & 0 deletions clickhouse/types/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace clickhouse {

using Int128 = absl::int128;
using UInt128 = absl::uint128;
using Int64 = int64_t;

using TypeRef = std::shared_ptr<class Type>;
Expand Down Expand Up @@ -43,6 +44,7 @@ class Type {
IPv4,
IPv6,
Int128,
UInt128,
Decimal,
Decimal32,
Decimal64,
Expand Down Expand Up @@ -339,6 +341,11 @@ inline TypeRef Type::CreateSimple<Int128>() {
return TypeRef(new Type(Int128));
}

template <>
inline TypeRef Type::CreateSimple<UInt128>() {
return TypeRef(new Type(UInt128));
}

template <>
inline TypeRef Type::CreateSimple<uint8_t>() {
return TypeRef(new Type(UInt8));
Expand Down
3 changes: 2 additions & 1 deletion ut/Column_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ using TestCases = ::testing::Types<
GenericColumnTestCase<ColumnIPv6, &makeColumn<ColumnIPv6>, in6_addr, &MakeIPv6s>,

GenericColumnTestCase<ColumnInt128, &makeColumn<ColumnInt128>, clickhouse::Int128, &MakeInt128s>,
GenericColumnTestCase<ColumnUInt128, &makeColumn<ColumnUInt128>, clickhouse::UInt128, &MakeUInt128s>,
GenericColumnTestCase<ColumnUUID, &makeColumn<ColumnUUID>, clickhouse::UUID, &MakeUUIDs>,

DecimalColumnTestCase<ColumnDecimal, 18, 0>,
Expand Down Expand Up @@ -286,7 +287,7 @@ inline auto convertValueForGetItem(const ColumnType& col, ValueType&& t) {
// Since ColumnDecimal can hold 32, 64, 128-bit wide data and there is no way telling at run-time.
const ItemView item = col.GetItem(0);
return std::string_view(reinterpret_cast<const char*>(&t), item.data.size());
} else if constexpr (std::is_same_v<T, clickhouse::UInt128>
} else if constexpr (std::is_same_v<T, clickhouse::UInt128> || std::is_same_v<T, clickhouse::UUID>
|| std::is_same_v<T, clickhouse::Int128>) {
return std::string_view{reinterpret_cast<const char*>(&t), sizeof(T)};
} else if constexpr (std::is_same_v<T, in_addr>) {
Expand Down
2 changes: 1 addition & 1 deletion ut/CreateColumnByType_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ INSTANTIATE_TEST_SUITE_P(Basic, CreateColumnByTypeWithName, ::testing::Values(
"Int8", "Int16", "Int32", "Int64",
"UInt8", "UInt16", "UInt32", "UInt64",
"String", "Date", "DateTime",
"UUID", "Int128"
"UUID", "Int128", "UInt128"
));

INSTANTIATE_TEST_SUITE_P(Parametrized, CreateColumnByTypeWithName, ::testing::Values(
Expand Down
22 changes: 22 additions & 0 deletions ut/columns_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,28 @@ TEST(ColumnsCase, Int128) {
EXPECT_EQ(0, col->At(4));
}

TEST(ColumnsCase, UInt128) {
auto col = std::make_shared<ColumnUInt128>(std::vector<UInt128>{
absl::MakeUint128(0xffffffffffffffffll, 0xffffffffffffffffll), // 2^128 - 1
absl::MakeUint128(0, 0xffffffffffffffffll), // 2^64 - 1
absl::MakeUint128(0xffffffffffffffffll, 0), // 2^128 - 2^64
absl::MakeUint128(0x8000000000000000ll, 0),
UInt128(0)
});

EXPECT_EQ(absl::MakeUint128(0xffffffffffffffffll, 0xffffffffffffffffll), col->At(0));

EXPECT_EQ(absl::MakeUint128(0, 0xffffffffffffffffll), col->At(1));
EXPECT_EQ(0ull, absl::Uint128High64(col->At(1)));
EXPECT_EQ(0xffffffffffffffffull, absl::Uint128Low64(col->At(1)));

EXPECT_EQ(absl::MakeUint128(0xffffffffffffffffll, 0), col->At(2));
EXPECT_EQ(static_cast<uint64_t>(0xffffffffffffffffull), absl::Uint128High64(col->At(2)));
EXPECT_EQ(0ull, absl::Uint128Low64(col->At(2)));

EXPECT_EQ(0, col->At(4));
}

TEST(ColumnsCase, ColumnIPv4)
{
// TODO: split into proper method-level unit-tests
Expand Down
12 changes: 11 additions & 1 deletion ut/value_generators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,23 @@ std::vector<clickhouse::Int64> MakeDateTimes() {
std::vector<clickhouse::Int128> MakeInt128s() {
return {
absl::MakeInt128(0xffffffffffffffffll, 0xffffffffffffffffll), // -1
absl::MakeInt128(0, 0xffffffffffffffffll), // 2^64
absl::MakeInt128(0, 0xffffffffffffffffll), // 2^64 - 1
absl::MakeInt128(0xffffffffffffffffll, 0),
absl::MakeInt128(0x8000000000000000ll, 0),
Int128(0)
};
}

std::vector<clickhouse::UInt128> MakeUInt128s() {
return {
absl::MakeUint128(0xffffffffffffffffll, 0xffffffffffffffffll), // 2^128 - 1
absl::MakeUint128(0, 0xffffffffffffffffll), // 2^64 - 1
absl::MakeUint128(0xffffffffffffffffll, 0), // 2^128 - 2^64
absl::MakeUint128(0x8000000000000000ll, 0),
UInt128(0)
};
}

std::vector<clickhouse::Int128> MakeDecimals(size_t /*precision*/, size_t scale) {
const auto scale_multiplier = static_cast<size_t>(std::pow(10, scale));
const long long int rhs_value = 12345678910;
Expand Down
1 change: 1 addition & 0 deletions ut/value_generators.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ std::vector<in_addr> MakeIPv4s();
std::vector<in6_addr> MakeIPv6s();
std::vector<clickhouse::UUID> MakeUUIDs();
std::vector<clickhouse::Int128> MakeInt128s();
std::vector<clickhouse::UInt128> MakeUInt128s();
std::vector<clickhouse::Int128> MakeDecimals(size_t precision, size_t scale);

template <typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
Expand Down