Skip to content

Commit 15a027e

Browse files
authored
Merge pull request #66 from CESNET/clickhouse-padding-fix
Clickhouse - fix ip padding
2 parents 766e02b + 45ecaf8 commit 15a027e

2 files changed

Lines changed: 41 additions & 7 deletions

File tree

modules/clickhouse/src/datatype.cpp

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010

1111
#include "datatype.hpp"
1212

13+
#include <algorithm>
14+
#include <array>
15+
#include <cstring>
1316
#include <iostream>
17+
#include <iterator>
1418

1519
template <unsigned Precision>
1620
class ColumnDateTime64 : public clickhouse::ColumnDateTime64 {
@@ -23,6 +27,28 @@ class ColumnDateTime64 : public clickhouse::ColumnDateTime64 {
2327

2428
namespace Getters {
2529

30+
static inline in6_addr toIn6(const Nemea::IpAddress& addr) noexcept
31+
{
32+
constexpr std::size_t ipv4MappedPrefixLen = 12U;
33+
constexpr std::size_t ipv4ByteLen = 4U;
34+
constexpr std::size_t ipv4Offset = 8U;
35+
36+
in6_addr out {};
37+
if (addr.isIpv4()) {
38+
static constexpr std::array<uint8_t, ipv4MappedPrefixLen>
39+
v4mapPrefix {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
40+
41+
std::copy(v4mapPrefix.begin(), v4mapPrefix.end(), out.s6_addr);
42+
std::copy(
43+
addr.ip.bytes + ipv4Offset,
44+
addr.ip.bytes + ipv4Offset + ipv4ByteLen,
45+
out.s6_addr + ipv4MappedPrefixLen);
46+
} else {
47+
std::memcpy(&out, &addr.ip, sizeof(out));
48+
}
49+
return out;
50+
}
51+
2652
template <typename Value>
2753
static Value getValue(Nemea::UnirecRecordView& record, ur_field_id_t fieldID)
2854
{
@@ -36,7 +62,7 @@ static std::vector<Value> getValueArr(Nemea::UnirecRecordView& record, ur_field_
3662
Nemea::UnirecArray<Value> const arr = record.getFieldAsUnirecArray<Value>(fieldID);
3763
std::vector<Value> result;
3864
result.reserve(arr.size());
39-
std::copy(arr.begin(), arr.end(), std::back_inserter(result));
65+
std::for_each(arr.begin(), arr.end(), [&](const Value& value) { result.push_back(value); });
4066
return result;
4167
}
4268

@@ -53,8 +79,8 @@ static std::vector<uint8_t> getBytes(Nemea::UnirecRecordView& record, ur_field_i
5379

5480
static in6_addr getIp(Nemea::UnirecRecordView& record, ur_field_id_t fieldID)
5581
{
56-
Nemea::IpAddress addr = record.getFieldAsType<Nemea::IpAddress>(fieldID);
57-
return *((in6_addr*) &addr.ip);
82+
const Nemea::IpAddress addr = record.getFieldAsType<Nemea::IpAddress>(fieldID);
83+
return toIn6(addr);
5884
}
5985

6086
static std::vector<in6_addr> getIpArr(Nemea::UnirecRecordView& record, ur_field_id_t fieldID)
@@ -67,9 +93,7 @@ static std::vector<in6_addr> getIpArr(Nemea::UnirecRecordView& record, ur_field_
6793
addrArr.begin(),
6894
addrArr.end(),
6995
std::back_inserter(result),
70-
[](const Nemea::IpAddress& value) -> in6_addr {
71-
return *reinterpret_cast<const in6_addr*>(&value.ip);
72-
});
96+
[](const Nemea::IpAddress& value) -> in6_addr { return toIn6(value); });
7397
return result;
7498
}
7599

modules/clickhouse/src/inserter.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,15 @@ static void ensureSchema(
146146
const auto& expectedType = typeToClickhouse(columns[i].type);
147147
const auto& [actual_name, actual_type] = dbColumns[i];
148148

149+
// strip Nullable(...) wrapper for comparison
150+
std::string actualBaseType = actual_type;
151+
static const std::string nullablePrefix = "Nullable(";
152+
if (actual_type.rfind(nullablePrefix, 0) == 0 && actual_type.back() == ')') {
153+
actualBaseType = actual_type.substr(
154+
nullablePrefix.size(),
155+
actual_type.size() - nullablePrefix.size() - 1);
156+
}
157+
149158
if (expectedName != actual_name) {
150159
std::stringstream sstream;
151160
sstream << "Expected column #" << i << " in table \"" << table << "\" to be named \""
@@ -154,7 +163,8 @@ static void ensureSchema(
154163
throw std::runtime_error(sstream.str());
155164
}
156165

157-
if (expectedType != actual_type) {
166+
// compare expected to stripped actual type
167+
if (expectedType != actualBaseType) {
158168
std::stringstream sstream;
159169
sstream << "Expected column #" << i << " in table \"" << table << "\" to be of type \""
160170
<< expectedType << "\" but it is \"" << actual_type << "\"\n"

0 commit comments

Comments
 (0)