mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-25 00:52:02 +00:00
dbms: ExternalDictionaries: remove most invididual getters
This commit is contained in:
parent
8ce8b602b6
commit
8ea2990e7d
@ -87,61 +87,11 @@ public:
|
|||||||
|
|
||||||
bool hasHierarchy() const override { return hierarchical_attribute; }
|
bool hasHierarchy() const override { return hierarchical_attribute; }
|
||||||
|
|
||||||
id_t toParent(const id_t id) const override
|
|
||||||
{
|
|
||||||
PODArray<UInt64> ids{1, id};
|
|
||||||
PODArray<UInt64> out{1};
|
|
||||||
getItems<UInt64>(*hierarchical_attribute, ids, out);
|
|
||||||
return out.front();
|
|
||||||
}
|
|
||||||
|
|
||||||
void toParent(const PODArray<id_t> & ids, PODArray<id_t> & out) const override
|
void toParent(const PODArray<id_t> & ids, PODArray<id_t> & out) const override
|
||||||
{
|
{
|
||||||
getItems<UInt64>(*hierarchical_attribute, ids, out);
|
getItems<UInt64>(*hierarchical_attribute, ids, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DECLARE_INDIVIDUAL_GETTER(TYPE) \
|
|
||||||
TYPE get##TYPE(const std::string & attribute_name, const id_t id) const override\
|
|
||||||
{\
|
|
||||||
auto & attribute = getAttribute(attribute_name);\
|
|
||||||
if (attribute.type != AttributeUnderlyingType::TYPE)\
|
|
||||||
throw Exception{\
|
|
||||||
"Type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
|
|
||||||
ErrorCodes::TYPE_MISMATCH\
|
|
||||||
};\
|
|
||||||
\
|
|
||||||
PODArray<UInt64> ids{1, id};\
|
|
||||||
PODArray<TYPE> out{1};\
|
|
||||||
getItems<TYPE>(attribute, ids, out);\
|
|
||||||
return out.front();\
|
|
||||||
}
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(UInt8)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(UInt16)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(UInt32)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(UInt64)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Int8)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Int16)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Int32)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Int64)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Float32)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Float64)
|
|
||||||
#undef DECLARE_INDIVIDUAL_GETTER
|
|
||||||
String getString(const std::string & attribute_name, const id_t id) const override
|
|
||||||
{
|
|
||||||
auto & attribute = getAttribute(attribute_name);
|
|
||||||
if (attribute.type != AttributeUnderlyingType::String)
|
|
||||||
throw Exception{
|
|
||||||
"Type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),
|
|
||||||
ErrorCodes::TYPE_MISMATCH
|
|
||||||
};
|
|
||||||
|
|
||||||
PODArray<UInt64> ids{1, id};
|
|
||||||
ColumnString out;
|
|
||||||
getItems(attribute, ids, &out);
|
|
||||||
|
|
||||||
return String{out.getDataAt(0)};
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DECLARE_MULTIPLE_GETTER(TYPE)\
|
#define DECLARE_MULTIPLE_GETTER(TYPE)\
|
||||||
void get##TYPE(const std::string & attribute_name, const PODArray<id_t> & ids, PODArray<TYPE> & out) const override\
|
void get##TYPE(const std::string & attribute_name, const PODArray<id_t> & ids, PODArray<TYPE> & out) const override\
|
||||||
{\
|
{\
|
||||||
|
@ -81,64 +81,11 @@ public:
|
|||||||
|
|
||||||
bool hasHierarchy() const override { return hierarchical_attribute; }
|
bool hasHierarchy() const override { return hierarchical_attribute; }
|
||||||
|
|
||||||
id_t toParent(const id_t id) const override
|
|
||||||
{
|
|
||||||
const auto attr = hierarchical_attribute;
|
|
||||||
const auto & array = *std::get<std::unique_ptr<PODArray<UInt64>>>(attr->arrays);
|
|
||||||
|
|
||||||
query_count.fetch_add(1, std::memory_order_relaxed);
|
|
||||||
|
|
||||||
return id < array.size() ? array[id] : std::get<UInt64>(attr->null_values);
|
|
||||||
}
|
|
||||||
|
|
||||||
void toParent(const PODArray<id_t> & ids, PODArray<id_t> & out) const override
|
void toParent(const PODArray<id_t> & ids, PODArray<id_t> & out) const override
|
||||||
{
|
{
|
||||||
getItems<UInt64>(*hierarchical_attribute, ids, out);
|
getItems<UInt64>(*hierarchical_attribute, ids, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DECLARE_INDIVIDUAL_GETTER(TYPE) \
|
|
||||||
TYPE get##TYPE(const std::string & attribute_name, const id_t id) const override\
|
|
||||||
{\
|
|
||||||
const auto & attribute = getAttribute(attribute_name);\
|
|
||||||
if (attribute.type != AttributeUnderlyingType::TYPE)\
|
|
||||||
throw Exception{\
|
|
||||||
"Type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
|
|
||||||
ErrorCodes::TYPE_MISMATCH\
|
|
||||||
};\
|
|
||||||
\
|
|
||||||
const auto & array = *std::get<std::unique_ptr<PODArray<TYPE>>>(attribute.arrays);\
|
|
||||||
\
|
|
||||||
query_count.fetch_add(1, std::memory_order_relaxed);\
|
|
||||||
\
|
|
||||||
return id < array.size() ? array[id] : std::get<TYPE>(attribute.null_values);\
|
|
||||||
}
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(UInt8)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(UInt16)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(UInt32)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(UInt64)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Int8)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Int16)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Int32)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Int64)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Float32)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Float64)
|
|
||||||
#undef DECLARE_INDIVIDUAL_GETTER
|
|
||||||
String getString(const std::string & attribute_name, const id_t id) const override
|
|
||||||
{
|
|
||||||
const auto & attribute = getAttribute(attribute_name);
|
|
||||||
if (attribute.type != AttributeUnderlyingType::String)
|
|
||||||
throw Exception{
|
|
||||||
"Type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),
|
|
||||||
ErrorCodes::TYPE_MISMATCH
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto & array = *std::get<std::unique_ptr<PODArray<StringRef>>>(attribute.arrays);
|
|
||||||
|
|
||||||
query_count.fetch_add(1, std::memory_order_relaxed);
|
|
||||||
|
|
||||||
return id < array.size() ? String{array[id]} : std::get<String>(attribute.null_values);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DECLARE_MULTIPLE_GETTER(TYPE)\
|
#define DECLARE_MULTIPLE_GETTER(TYPE)\
|
||||||
void get##TYPE(const std::string & attribute_name, const PODArray<id_t> & ids, PODArray<TYPE> & out) const override\
|
void get##TYPE(const std::string & attribute_name, const PODArray<id_t> & ids, PODArray<TYPE> & out) const override\
|
||||||
{\
|
{\
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -78,67 +79,11 @@ public:
|
|||||||
|
|
||||||
bool hasHierarchy() const override { return hierarchical_attribute; }
|
bool hasHierarchy() const override { return hierarchical_attribute; }
|
||||||
|
|
||||||
id_t toParent(const id_t id) const override
|
|
||||||
{
|
|
||||||
const auto attr = hierarchical_attribute;
|
|
||||||
const auto & map = *std::get<std::unique_ptr<HashMap<UInt64, UInt64>>>(attr->maps);
|
|
||||||
const auto it = map.find(id);
|
|
||||||
|
|
||||||
query_count.fetch_add(1, std::memory_order_relaxed);
|
|
||||||
|
|
||||||
return it != map.end() ? it->second : std::get<UInt64>(attr->null_values);
|
|
||||||
}
|
|
||||||
|
|
||||||
void toParent(const PODArray<id_t> & ids, PODArray<id_t> & out) const override
|
void toParent(const PODArray<id_t> & ids, PODArray<id_t> & out) const override
|
||||||
{
|
{
|
||||||
getItems<UInt64>(*hierarchical_attribute, ids, out);
|
getItems<UInt64>(*hierarchical_attribute, ids, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DECLARE_INDIVIDUAL_GETTER(TYPE) \
|
|
||||||
TYPE get##TYPE(const std::string & attribute_name, const id_t id) const override\
|
|
||||||
{\
|
|
||||||
const auto & attribute = getAttribute(attribute_name);\
|
|
||||||
if (attribute.type != AttributeUnderlyingType::TYPE)\
|
|
||||||
throw Exception{\
|
|
||||||
"Type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
|
|
||||||
ErrorCodes::TYPE_MISMATCH\
|
|
||||||
};\
|
|
||||||
\
|
|
||||||
const auto & map = *std::get<std::unique_ptr<HashMap<UInt64, TYPE>>>(attribute.maps);\
|
|
||||||
const auto it = map.find(id);\
|
|
||||||
\
|
|
||||||
query_count.fetch_add(1, std::memory_order_relaxed);\
|
|
||||||
\
|
|
||||||
return it != map.end() ? TYPE{it->second} : std::get<TYPE>(attribute.null_values);\
|
|
||||||
}
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(UInt8)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(UInt16)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(UInt32)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(UInt64)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Int8)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Int16)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Int32)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Int64)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Float32)
|
|
||||||
DECLARE_INDIVIDUAL_GETTER(Float64)
|
|
||||||
#undef DECLARE_INDIVIDUAL_GETTER
|
|
||||||
String getString(const std::string & attribute_name, const id_t id) const override
|
|
||||||
{
|
|
||||||
const auto & attribute = getAttribute(attribute_name);
|
|
||||||
if (attribute.type != AttributeUnderlyingType::String)
|
|
||||||
throw Exception{
|
|
||||||
"Type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),
|
|
||||||
ErrorCodes::TYPE_MISMATCH
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto & map = *std::get<std::unique_ptr<HashMap<UInt64, StringRef>>>(attribute.maps);
|
|
||||||
const auto it = map.find(id);
|
|
||||||
|
|
||||||
query_count.fetch_add(1, std::memory_order_relaxed);
|
|
||||||
|
|
||||||
return it != map.end() ? String{it->second} : std::get<String>(attribute.null_values);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DECLARE_MULTIPLE_GETTER(TYPE)\
|
#define DECLARE_MULTIPLE_GETTER(TYPE)\
|
||||||
void get##TYPE(const std::string & attribute_name, const PODArray<id_t> & ids, PODArray<TYPE> & out) const override\
|
void get##TYPE(const std::string & attribute_name, const PODArray<id_t> & ids, PODArray<TYPE> & out) const override\
|
||||||
{\
|
{\
|
||||||
|
@ -56,7 +56,16 @@ public:
|
|||||||
virtual bool hasHierarchy() const = 0;
|
virtual bool hasHierarchy() const = 0;
|
||||||
|
|
||||||
/// do not call unless you ensure that hasHierarchy() returns true
|
/// do not call unless you ensure that hasHierarchy() returns true
|
||||||
virtual id_t toParent(id_t id) const = 0;
|
id_t toParent(id_t id) const
|
||||||
|
{
|
||||||
|
const PODArray<UInt64> ids(1, id);
|
||||||
|
PODArray<UInt64> out(1);
|
||||||
|
|
||||||
|
toParent(ids, out);
|
||||||
|
|
||||||
|
return out.front();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void toParent(const PODArray<id_t> & ids, PODArray<id_t> & out) const = 0;
|
virtual void toParent(const PODArray<id_t> & ids, PODArray<id_t> & out) const = 0;
|
||||||
|
|
||||||
bool in(id_t child_id, const id_t ancestor_id) const
|
bool in(id_t child_id, const id_t ancestor_id) const
|
||||||
@ -67,20 +76,7 @@ public:
|
|||||||
return child_id != 0;
|
return child_id != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// functions for individual access
|
/// return mapped values for a collection of identifiers
|
||||||
virtual UInt8 getUInt8(const std::string & attribute_name, id_t id) const = 0;
|
|
||||||
virtual UInt16 getUInt16(const std::string & attribute_name, id_t id) const = 0;
|
|
||||||
virtual UInt32 getUInt32(const std::string & attribute_name, id_t id) const = 0;
|
|
||||||
virtual UInt64 getUInt64(const std::string & attribute_name, id_t id) const = 0;
|
|
||||||
virtual Int8 getInt8(const std::string & attribute_name, id_t id) const = 0;
|
|
||||||
virtual Int16 getInt16(const std::string & attribute_name, id_t id) const = 0;
|
|
||||||
virtual Int32 getInt32(const std::string & attribute_name, id_t id) const = 0;
|
|
||||||
virtual Int64 getInt64(const std::string & attribute_name, id_t id) const = 0;
|
|
||||||
virtual Float32 getFloat32(const std::string & attribute_name, id_t id) const = 0;
|
|
||||||
virtual Float64 getFloat64(const std::string & attribute_name, id_t id) const = 0;
|
|
||||||
virtual String getString(const std::string & attribute_name, id_t id) const = 0;
|
|
||||||
|
|
||||||
/// functions for multiple access
|
|
||||||
virtual void getUInt8(const std::string & attr_name, const PODArray<id_t> & ids, PODArray<UInt8> & out) const = 0;
|
virtual void getUInt8(const std::string & attr_name, const PODArray<id_t> & ids, PODArray<UInt8> & out) const = 0;
|
||||||
virtual void getUInt16(const std::string & attr_name, const PODArray<id_t> & ids, PODArray<UInt16> & out) const = 0;
|
virtual void getUInt16(const std::string & attr_name, const PODArray<id_t> & ids, PODArray<UInt16> & out) const = 0;
|
||||||
virtual void getUInt32(const std::string & attr_name, const PODArray<id_t> & ids, PODArray<UInt32> & out) const = 0;
|
virtual void getUInt32(const std::string & attr_name, const PODArray<id_t> & ids, PODArray<UInt32> & out) const = 0;
|
||||||
|
@ -839,9 +839,12 @@ private:
|
|||||||
}
|
}
|
||||||
else if (const auto id_col = typeid_cast<const ColumnConst<UInt64> *>(id_col_untyped))
|
else if (const auto id_col = typeid_cast<const ColumnConst<UInt64> *>(id_col_untyped))
|
||||||
{
|
{
|
||||||
|
const PODArray<UInt64> ids{1, id_col->getData()};
|
||||||
|
auto out = std::make_unique<ColumnString>();
|
||||||
|
dictionary->getString(attr_name, ids, out.get());
|
||||||
|
|
||||||
block.getByPosition(result).column = new ColumnConst<String>{
|
block.getByPosition(result).column = new ColumnConst<String>{
|
||||||
id_col->size(),
|
id_col->size(), out->getDataAtWithTerminatingZero(0).toString()
|
||||||
dictionary->getString(attr_name, id_col->getData())
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -863,10 +866,6 @@ template <typename DataType> struct DictGetTraits;
|
|||||||
#define DECLARE_DICT_GET_TRAITS(TYPE, DATA_TYPE) \
|
#define DECLARE_DICT_GET_TRAITS(TYPE, DATA_TYPE) \
|
||||||
template <> struct DictGetTraits<DATA_TYPE>\
|
template <> struct DictGetTraits<DATA_TYPE>\
|
||||||
{\
|
{\
|
||||||
static TYPE get(const IDictionary * const dict, const std::string & name, const IDictionary::id_t id)\
|
|
||||||
{\
|
|
||||||
return dict->get##TYPE(name, id);\
|
|
||||||
}\
|
|
||||||
static void get(const IDictionary * const dict, const std::string & name, const PODArray<IDictionary::id_t> & ids, PODArray<TYPE> & out)\
|
static void get(const IDictionary * const dict, const std::string & name, const PODArray<IDictionary::id_t> & ids, PODArray<TYPE> & out)\
|
||||||
{\
|
{\
|
||||||
dict->get##TYPE(name, ids, out);\
|
dict->get##TYPE(name, ids, out);\
|
||||||
@ -996,10 +995,11 @@ private:
|
|||||||
}
|
}
|
||||||
else if (const auto id_col = typeid_cast<const ColumnConst<UInt64> *>(id_col_untyped))
|
else if (const auto id_col = typeid_cast<const ColumnConst<UInt64> *>(id_col_untyped))
|
||||||
{
|
{
|
||||||
block.getByPosition(result).column = new ColumnConst<Type>{
|
const PODArray<UInt64> ids{1, id_col->getData()};
|
||||||
id_col->size(),
|
PODArray<Type> data(1);
|
||||||
DictGetTraits<DataType>::get(dictionary, attr_name, id_col->getData())
|
DictGetTraits<DataType>::get(dictionary, attr_name, ids, data);
|
||||||
};
|
|
||||||
|
block.getByPosition(result).column = new ColumnConst<Type>{id_col->size(), data.front()};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1113,10 +1113,7 @@ private:
|
|||||||
if (!dict)
|
if (!dict)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto id_col_untyped = block.getByPosition(arguments[1]).column.get();
|
const auto get_hierarchies = [&] (const PODArray<UInt64> & in, PODArray<UInt64> & out, PODArray<UInt64> & offsets) {
|
||||||
if (const auto id_col = typeid_cast<const ColumnVector<UInt64> *>(id_col_untyped))
|
|
||||||
{
|
|
||||||
const auto & in = id_col->getData();
|
|
||||||
const auto size = in.size();
|
const auto size = in.size();
|
||||||
|
|
||||||
/// copy of `in` array
|
/// copy of `in` array
|
||||||
@ -1157,12 +1154,6 @@ private:
|
|||||||
std::swap(in_array, out_array);
|
std::swap(in_array, out_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto backend = new ColumnVector<UInt64>;
|
|
||||||
const auto array = new ColumnArray{backend};
|
|
||||||
block.getByPosition(result).column = array;
|
|
||||||
|
|
||||||
auto & out = backend->getData();
|
|
||||||
auto & offsets = array->getOffsets();
|
|
||||||
out.reserve(total_count);
|
out.reserve(total_count);
|
||||||
offsets.resize(size);
|
offsets.resize(size);
|
||||||
|
|
||||||
@ -1172,21 +1163,29 @@ private:
|
|||||||
out.insert_assume_reserved(std::begin(ids), std::end(ids));
|
out.insert_assume_reserved(std::begin(ids), std::end(ids));
|
||||||
offsets[i] = out.size();
|
offsets[i] = out.size();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto id_col_untyped = block.getByPosition(arguments[1]).column.get();
|
||||||
|
if (const auto id_col = typeid_cast<const ColumnVector<UInt64> *>(id_col_untyped))
|
||||||
|
{
|
||||||
|
const auto & in = id_col->getData();
|
||||||
|
const auto backend = new ColumnVector<UInt64>;
|
||||||
|
const auto array = new ColumnArray{backend};
|
||||||
|
block.getByPosition(result).column = array;
|
||||||
|
|
||||||
|
get_hierarchies(in, backend->getData(), array->getOffsets());
|
||||||
}
|
}
|
||||||
else if (const auto id_col = typeid_cast<const ColumnConst<UInt64> *>(id_col_untyped))
|
else if (const auto id_col = typeid_cast<const ColumnConst<UInt64> *>(id_col_untyped))
|
||||||
{
|
{
|
||||||
Array res;
|
const PODArray<UInt64> in(1, id_col->getData());
|
||||||
|
const auto backend = new ColumnVector<UInt64>;
|
||||||
|
const auto array = new ColumnArray{backend};
|
||||||
|
|
||||||
IDictionary::id_t cur = id_col->getData();
|
get_hierarchies(in, backend->getData(), array->getOffsets());
|
||||||
while (cur)
|
|
||||||
{
|
|
||||||
res.push_back(cur);
|
|
||||||
cur = dictionary->toParent(cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
block.getByPosition(result).column = new ColumnConstArray{
|
block.getByPosition(result).column = new ColumnConstArray{
|
||||||
id_col->size(),
|
id_col->size(),
|
||||||
res,
|
(*array)[0].get<Array>(),
|
||||||
new DataTypeArray{new DataTypeUInt64}
|
new DataTypeArray{new DataTypeUInt64}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user