fix bin, hex

This commit is contained in:
Yakov Olkhovskiy 2022-11-15 04:57:08 +00:00
parent f4cb27237e
commit 324c3bb81e

View File

@ -326,7 +326,9 @@ public:
tryExecuteDecimal<Decimal32>(column, res_column) ||
tryExecuteDecimal<Decimal64>(column, res_column) ||
tryExecuteDecimal<Decimal128>(column, res_column) ||
tryExecuteUUID(column, res_column))
tryExecuteUUID(column, res_column) ||
tryExecuteIPv4(column, res_column) ||
tryExecuteIPv6(column, res_column))
return res_column;
throw Exception("Illegal column " + arguments[0].column->getName()
@ -548,6 +550,88 @@ public:
return false;
}
}
bool tryExecuteIPv6(const IColumn * col, ColumnPtr & col_res) const
{
const ColumnIPv6 * col_vec = checkAndGetColumn<ColumnIPv6>(col);
static constexpr size_t MAX_LENGTH = sizeof(IPv6) * word_size + 1; /// Including trailing zero byte.
if (!col_vec)
return false;
auto col_str = ColumnString::create();
ColumnString::Chars & out_vec = col_str->getChars();
ColumnString::Offsets & out_offsets = col_str->getOffsets();
const typename ColumnIPv6::Container & in_vec = col_vec->getData();
const IPv6* ip = in_vec.data();
size_t size = in_vec.size();
out_offsets.resize(size);
out_vec.resize(size * (word_size+1) + MAX_LENGTH); /// word_size+1 is length of one byte in hex/bin plus zero byte.
size_t pos = 0;
for (size_t i = 0; i < size; ++i)
{
/// Manual exponential growth, so as not to rely on the linear amortized work time of `resize` (no one guarantees it).
if (pos + MAX_LENGTH > out_vec.size())
out_vec.resize(out_vec.size() * word_size + MAX_LENGTH);
char * begin = reinterpret_cast<char *>(&out_vec[pos]);
char * end = begin;
Impl::executeOneString(reinterpret_cast<const UInt8 *>(&ip[i].toUnderType().items[0]), reinterpret_cast<const UInt8 *>(&ip[i].toUnderType().items[2]), end);
pos += end - begin;
out_offsets[i] = pos;
}
out_vec.resize(pos);
col_res = std::move(col_str);
return true;
}
bool tryExecuteIPv4(const IColumn * col, ColumnPtr & col_res) const
{
const ColumnIPv4 * col_vec = checkAndGetColumn<ColumnIPv4>(col);
static constexpr size_t MAX_LENGTH = sizeof(IPv4) * word_size + 1; /// Including trailing zero byte.
if (!col_vec)
return false;
auto col_str = ColumnString::create();
ColumnString::Chars & out_vec = col_str->getChars();
ColumnString::Offsets & out_offsets = col_str->getOffsets();
const typename ColumnIPv4::Container & in_vec = col_vec->getData();
const IPv4* ip = in_vec.data();
size_t size = in_vec.size();
out_offsets.resize(size);
out_vec.resize(size * (word_size+1) + MAX_LENGTH); /// word_size+1 is length of one byte in hex/bin plus zero byte.
size_t pos = 0;
for (size_t i = 0; i < size; ++i)
{
/// Manual exponential growth, so as not to rely on the linear amortized work time of `resize` (no one guarantees it).
if (pos + MAX_LENGTH > out_vec.size())
out_vec.resize(out_vec.size() * word_size + MAX_LENGTH);
char * begin = reinterpret_cast<char *>(&out_vec[pos]);
char * end = begin;
Impl::executeOneUIntOrInt(ip[i].toUnderType(), end);
pos += end - begin;
out_offsets[i] = pos;
}
out_vec.resize(pos);
col_res = std::move(col_str);
return true;
}
};
/// Decode number or string from string with binary or hexadecimal representation