Merge pull request #45585 from kitaisreal/low-cardinality-insert-fix

LowCardinality insert fix
This commit is contained in:
Alexey Milovidov 2023-01-28 03:26:40 +03:00 committed by GitHub
commit 9b1b247f9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 37 deletions

View File

@ -331,46 +331,14 @@ size_t ColumnUnique<ColumnType>::getNullValueIndex() const
template <typename ColumnType>
size_t ColumnUnique<ColumnType>::uniqueInsert(const Field & x)
{
class FieldVisitorGetData : public StaticVisitor<>
{
public:
StringRef res;
[[noreturn]] static void throwUnsupported()
{
throw Exception(ErrorCodes::LOGICAL_ERROR, "Unsupported field type");
}
[[noreturn]] void operator() (const Null &) { throwUnsupported(); }
[[noreturn]] void operator() (const Array &) { throwUnsupported(); }
[[noreturn]] void operator() (const Tuple &) { throwUnsupported(); }
[[noreturn]] void operator() (const Map &) { throwUnsupported(); }
[[noreturn]] void operator() (const Object &) { throwUnsupported(); }
[[noreturn]] void operator() (const AggregateFunctionStateData &) { throwUnsupported(); }
void operator() (const String & x) { res = {x.data(), x.size()}; }
void operator() (const UInt64 & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const UInt128 & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const UInt256 & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const Int64 & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const Int128 & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const Int256 & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const UUID & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const IPv4 & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const IPv6 & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const Float64 & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const DecimalField<Decimal32> & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const DecimalField<Decimal64> & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const DecimalField<Decimal128> & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const DecimalField<Decimal256> & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
void operator() (const bool & x) { res = {reinterpret_cast<const char *>(&x), sizeof(x)}; }
};
if (x.isNull())
return getNullValueIndex();
FieldVisitorGetData visitor;
applyVisitor(visitor, x);
return uniqueInsertData(visitor.res.data, visitor.res.size);
auto single_value_column = column_holder->cloneEmpty();
single_value_column->insert(x);
auto single_value_data = single_value_column->getDataAt(0);
return uniqueInsertData(single_value_data.data, single_value_data.size);
}
template <typename ColumnType>

View File

@ -0,0 +1,50 @@
#include <Columns/ColumnLowCardinality.h>
#include <Columns/ColumnsNumber.h>
#include <DataTypes/DataTypesNumber.h>
#include <DataTypes/DataTypeLowCardinality.h>
#include <gtest/gtest.h>
using namespace DB;
template <typename T>
void testLowCardinalityNumberInsert(const DataTypePtr & data_type)
{
auto low_cardinality_type = std::make_shared<DataTypeLowCardinality>(data_type);
auto column = low_cardinality_type->createColumn();
column->insert(static_cast<T>(15));
column->insert(static_cast<T>(20));
column->insert(static_cast<T>(25));
Field value;
column->get(0, value);
ASSERT_EQ(value.get<T>(), 15);
column->get(1, value);
ASSERT_EQ(value.get<T>(), 20);
column->get(2, value);
ASSERT_EQ(value.get<T>(), 25);
}
TEST(ColumnLowCardinality, Insert)
{
testLowCardinalityNumberInsert<UInt8>(std::make_shared<DataTypeUInt8>());
testLowCardinalityNumberInsert<UInt16>(std::make_shared<DataTypeUInt16>());
testLowCardinalityNumberInsert<UInt32>(std::make_shared<DataTypeUInt32>());
testLowCardinalityNumberInsert<UInt64>(std::make_shared<DataTypeUInt64>());
testLowCardinalityNumberInsert<UInt128>(std::make_shared<DataTypeUInt128>());
testLowCardinalityNumberInsert<UInt256>(std::make_shared<DataTypeUInt256>());
testLowCardinalityNumberInsert<Int8>(std::make_shared<DataTypeInt8>());
testLowCardinalityNumberInsert<Int16>(std::make_shared<DataTypeInt16>());
testLowCardinalityNumberInsert<Int32>(std::make_shared<DataTypeInt32>());
testLowCardinalityNumberInsert<Int64>(std::make_shared<DataTypeInt64>());
testLowCardinalityNumberInsert<Int128>(std::make_shared<DataTypeInt128>());
testLowCardinalityNumberInsert<Int256>(std::make_shared<DataTypeInt256>());
testLowCardinalityNumberInsert<Float32>(std::make_shared<DataTypeFloat32>());
testLowCardinalityNumberInsert<Float64>(std::make_shared<DataTypeFloat64>());
}