mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12: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; }
|
||||
|
||||
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
|
||||
{
|
||||
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)\
|
||||
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; }
|
||||
|
||||
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
|
||||
{
|
||||
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)\
|
||||
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 <tuple>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
@ -78,67 +79,11 @@ public:
|
||||
|
||||
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
|
||||
{
|
||||
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)\
|
||||
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;
|
||||
|
||||
/// 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;
|
||||
|
||||
bool in(id_t child_id, const id_t ancestor_id) const
|
||||
@ -67,20 +76,7 @@ public:
|
||||
return child_id != 0;
|
||||
}
|
||||
|
||||
/// functions for individual access
|
||||
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
|
||||
/// return mapped values for a collection of identifiers
|
||||
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 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))
|
||||
{
|
||||
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>{
|
||||
id_col->size(),
|
||||
dictionary->getString(attr_name, id_col->getData())
|
||||
id_col->size(), out->getDataAtWithTerminatingZero(0).toString()
|
||||
};
|
||||
}
|
||||
else
|
||||
@ -863,10 +866,6 @@ template <typename DataType> struct DictGetTraits;
|
||||
#define DECLARE_DICT_GET_TRAITS(TYPE, 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)\
|
||||
{\
|
||||
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))
|
||||
{
|
||||
block.getByPosition(result).column = new ColumnConst<Type>{
|
||||
id_col->size(),
|
||||
DictGetTraits<DataType>::get(dictionary, attr_name, id_col->getData())
|
||||
};
|
||||
const PODArray<UInt64> ids{1, id_col->getData()};
|
||||
PODArray<Type> data(1);
|
||||
DictGetTraits<DataType>::get(dictionary, attr_name, ids, data);
|
||||
|
||||
block.getByPosition(result).column = new ColumnConst<Type>{id_col->size(), data.front()};
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1113,10 +1113,7 @@ private:
|
||||
if (!dict)
|
||||
return false;
|
||||
|
||||
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 get_hierarchies = [&] (const PODArray<UInt64> & in, PODArray<UInt64> & out, PODArray<UInt64> & offsets) {
|
||||
const auto size = in.size();
|
||||
|
||||
/// copy of `in` array
|
||||
@ -1157,12 +1154,6 @@ private:
|
||||
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);
|
||||
offsets.resize(size);
|
||||
|
||||
@ -1172,21 +1163,29 @@ private:
|
||||
out.insert_assume_reserved(std::begin(ids), std::end(ids));
|
||||
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))
|
||||
{
|
||||
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();
|
||||
while (cur)
|
||||
{
|
||||
res.push_back(cur);
|
||||
cur = dictionary->toParent(cur);
|
||||
}
|
||||
get_hierarchies(in, backend->getData(), array->getOffsets());
|
||||
|
||||
block.getByPosition(result).column = new ColumnConstArray{
|
||||
id_col->size(),
|
||||
res,
|
||||
(*array)[0].get<Array>(),
|
||||
new DataTypeArray{new DataTypeUInt64}
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user