Skip to content
Merged
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
36 changes: 30 additions & 6 deletions modules/clickhouse/src/datatype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@

#include "datatype.hpp"

#include <algorithm>
#include <array>
#include <cstring>
#include <iostream>
#include <iterator>

template <unsigned Precision>
class ColumnDateTime64 : public clickhouse::ColumnDateTime64 {
Expand All @@ -23,6 +27,28 @@ class ColumnDateTime64 : public clickhouse::ColumnDateTime64 {

namespace Getters {

static inline in6_addr toIn6(const Nemea::IpAddress& addr) noexcept
{
constexpr std::size_t ipv4MappedPrefixLen = 12U;
constexpr std::size_t ipv4ByteLen = 4U;
constexpr std::size_t ipv4Offset = 8U;

in6_addr out {};
if (addr.isIpv4()) {
static constexpr std::array<uint8_t, ipv4MappedPrefixLen>
v4mapPrefix {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};

std::copy(v4mapPrefix.begin(), v4mapPrefix.end(), out.s6_addr);
std::copy(
addr.ip.bytes + ipv4Offset,
addr.ip.bytes + ipv4Offset + ipv4ByteLen,
out.s6_addr + ipv4MappedPrefixLen);
} else {
std::memcpy(&out, &addr.ip, sizeof(out));
}
return out;
}

template <typename Value>
static Value getValue(Nemea::UnirecRecordView& record, ur_field_id_t fieldID)
{
Expand All @@ -36,7 +62,7 @@ static std::vector<Value> getValueArr(Nemea::UnirecRecordView& record, ur_field_
Nemea::UnirecArray<Value> const arr = record.getFieldAsUnirecArray<Value>(fieldID);
std::vector<Value> result;
result.reserve(arr.size());
std::copy(arr.begin(), arr.end(), std::back_inserter(result));
std::for_each(arr.begin(), arr.end(), [&](const Value& value) { result.push_back(value); });
return result;
}

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

static in6_addr getIp(Nemea::UnirecRecordView& record, ur_field_id_t fieldID)
{
Nemea::IpAddress addr = record.getFieldAsType<Nemea::IpAddress>(fieldID);
return *((in6_addr*) &addr.ip);
const Nemea::IpAddress addr = record.getFieldAsType<Nemea::IpAddress>(fieldID);
return toIn6(addr);
}

static std::vector<in6_addr> getIpArr(Nemea::UnirecRecordView& record, ur_field_id_t fieldID)
Expand All @@ -67,9 +93,7 @@ static std::vector<in6_addr> getIpArr(Nemea::UnirecRecordView& record, ur_field_
addrArr.begin(),
addrArr.end(),
std::back_inserter(result),
[](const Nemea::IpAddress& value) -> in6_addr {
return *reinterpret_cast<const in6_addr*>(&value.ip);
});
[](const Nemea::IpAddress& value) -> in6_addr { return toIn6(value); });
return result;
}

Expand Down
12 changes: 11 additions & 1 deletion modules/clickhouse/src/inserter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,15 @@ static void ensureSchema(
const auto& expectedType = typeToClickhouse(columns[i].type);
const auto& [actual_name, actual_type] = dbColumns[i];

// strip Nullable(...) wrapper for comparison
std::string actualBaseType = actual_type;
static const std::string nullablePrefix = "Nullable(";
if (actual_type.rfind(nullablePrefix, 0) == 0 && actual_type.back() == ')') {
actualBaseType = actual_type.substr(
nullablePrefix.size(),
actual_type.size() - nullablePrefix.size() - 1);
}

if (expectedName != actual_name) {
std::stringstream sstream;
sstream << "Expected column #" << i << " in table \"" << table << "\" to be named \""
Expand All @@ -154,7 +163,8 @@ static void ensureSchema(
throw std::runtime_error(sstream.str());
}

if (expectedType != actual_type) {
// compare expected to stripped actual type
if (expectedType != actualBaseType) {
std::stringstream sstream;
sstream << "Expected column #" << i << " in table \"" << table << "\" to be of type \""
<< expectedType << "\" but it is \"" << actual_type << "\"\n"
Expand Down