Skip to content

Commit ea9166f

Browse files
committed
Clickhouse - fix ip padding
1 parent 766e02b commit ea9166f

2 files changed

Lines changed: 30 additions & 6 deletions

File tree

modules/clickhouse/src/datatype.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010

1111
#include "datatype.hpp"
1212

13+
#include <algorithm>
14+
#include <cstring>
1315
#include <iostream>
16+
#include <iterator>
1417

1518
template <unsigned Precision>
1619
class ColumnDateTime64 : public clickhouse::ColumnDateTime64 {
@@ -23,6 +26,19 @@ class ColumnDateTime64 : public clickhouse::ColumnDateTime64 {
2326

2427
namespace Getters {
2528

29+
static inline in6_addr toIn6(const Nemea::IpAddress& addr) noexcept
30+
{
31+
in6_addr out {};
32+
if (addr.isIpv4()) {
33+
static constexpr uint8_t v4map_prefix[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
34+
std::memcpy(out.s6_addr, v4map_prefix, 12);
35+
std::memcpy(out.s6_addr + 12, &addr.ip.bytes[8], 4);
36+
} else {
37+
std::memcpy(&out, &addr.ip, sizeof(out));
38+
}
39+
return out;
40+
}
41+
2642
template <typename Value>
2743
static Value getValue(Nemea::UnirecRecordView& record, ur_field_id_t fieldID)
2844
{
@@ -36,7 +52,7 @@ static std::vector<Value> getValueArr(Nemea::UnirecRecordView& record, ur_field_
3652
Nemea::UnirecArray<Value> const arr = record.getFieldAsUnirecArray<Value>(fieldID);
3753
std::vector<Value> result;
3854
result.reserve(arr.size());
39-
std::copy(arr.begin(), arr.end(), std::back_inserter(result));
55+
std::for_each(arr.begin(), arr.end(), [&](const Value& value) { result.push_back(value); });
4056
return result;
4157
}
4258

@@ -54,7 +70,7 @@ static std::vector<uint8_t> getBytes(Nemea::UnirecRecordView& record, ur_field_i
5470
static in6_addr getIp(Nemea::UnirecRecordView& record, ur_field_id_t fieldID)
5571
{
5672
Nemea::IpAddress addr = record.getFieldAsType<Nemea::IpAddress>(fieldID);
57-
return *((in6_addr*) &addr.ip);
73+
return toIn6(addr);
5874
}
5975

6076
static std::vector<in6_addr> getIpArr(Nemea::UnirecRecordView& record, ur_field_id_t fieldID)
@@ -67,9 +83,7 @@ static std::vector<in6_addr> getIpArr(Nemea::UnirecRecordView& record, ur_field_
6783
addrArr.begin(),
6884
addrArr.end(),
6985
std::back_inserter(result),
70-
[](const Nemea::IpAddress& value) -> in6_addr {
71-
return *reinterpret_cast<const in6_addr*>(&value.ip);
72-
});
86+
[](const Nemea::IpAddress& value) -> in6_addr { return toIn6(value); });
7387
return result;
7488
}
7589

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)