fix DictionaryBlockInputStream::getBlock for empty dictionary

This commit is contained in:
Nikolai Kochetov 2018-03-07 17:29:00 +03:00
parent 68357f3534
commit 3f5218bb11

View File

@ -114,6 +114,15 @@ private:
Columns data_columns; Columns data_columns;
GetColumnsFunction get_key_columns_function; GetColumnsFunction get_key_columns_function;
GetColumnsFunction get_view_columns_function; GetColumnsFunction get_view_columns_function;
enum class DictionaryKeyType
{
Id,
ComplexKey,
Callback
};
DictionaryKeyType key_type;
}; };
template <typename DictionaryType, typename Key> template <typename DictionaryType, typename Key>
@ -124,7 +133,8 @@ DictionaryBlockInputStream<DictionaryType, Key>::DictionaryBlockInputStream(
dictionary(std::static_pointer_cast<const DictionaryType>(dictionary)), dictionary(std::static_pointer_cast<const DictionaryType>(dictionary)),
column_names(column_names), ids(std::move(ids)), column_names(column_names), ids(std::move(ids)),
logger(&Poco::Logger::get("DictionaryBlockInputStream")), logger(&Poco::Logger::get("DictionaryBlockInputStream")),
fillBlockFunction(&DictionaryBlockInputStream<DictionaryType, Key>::fillBlock<DictionaryGetter, DictionaryStringGetter>) fillBlockFunction(&DictionaryBlockInputStream<DictionaryType, Key>::fillBlock<DictionaryGetter, DictionaryStringGetter>),
key_type(DictionaryKeyType::Id)
{ {
} }
@ -135,7 +145,8 @@ DictionaryBlockInputStream<DictionaryType, Key>::DictionaryBlockInputStream(
: DictionaryBlockInputStreamBase(keys.size(), max_block_size), : DictionaryBlockInputStreamBase(keys.size(), max_block_size),
dictionary(std::static_pointer_cast<const DictionaryType>(dictionary)), column_names(column_names), dictionary(std::static_pointer_cast<const DictionaryType>(dictionary)), column_names(column_names),
logger(&Poco::Logger::get("DictionaryBlockInputStream")), logger(&Poco::Logger::get("DictionaryBlockInputStream")),
fillBlockFunction(&DictionaryBlockInputStream<DictionaryType, Key>::fillBlock<GetterByKey, StringGetterByKey>) fillBlockFunction(&DictionaryBlockInputStream<DictionaryType, Key>::fillBlock<GetterByKey, StringGetterByKey>),
key_type(DictionaryKeyType::ComplexKey)
{ {
const DictionaryStructure & dictionaty_structure = dictionary->getStructure(); const DictionaryStructure & dictionaty_structure = dictionary->getStructure();
fillKeyColumns(keys, 0, keys.size(), dictionaty_structure, key_columns); fillKeyColumns(keys, 0, keys.size(), dictionaty_structure, key_columns);
@ -152,50 +163,55 @@ DictionaryBlockInputStream<DictionaryType, Key>::DictionaryBlockInputStream(
logger(&Poco::Logger::get("DictionaryBlockInputStream")), logger(&Poco::Logger::get("DictionaryBlockInputStream")),
fillBlockFunction(&DictionaryBlockInputStream<DictionaryType, Key>::fillBlock<GetterByKey, StringGetterByKey>), fillBlockFunction(&DictionaryBlockInputStream<DictionaryType, Key>::fillBlock<GetterByKey, StringGetterByKey>),
data_columns(data_columns), data_columns(data_columns),
get_key_columns_function(get_key_columns_function), get_view_columns_function(get_view_columns_function) get_key_columns_function(get_key_columns_function), get_view_columns_function(get_view_columns_function),
key_type(DictionaryKeyType::Callback)
{ {
} }
template <typename DictionaryType, typename Key> template <typename DictionaryType, typename Key>
Block DictionaryBlockInputStream<DictionaryType, Key>::getBlock(size_t start, size_t length) const Block DictionaryBlockInputStream<DictionaryType, Key>::getBlock(size_t start, size_t length) const
{ {
if (!key_columns.empty()) switch (key_type)
{ {
Columns columns; case DictionaryKeyType::ComplexKey:
ColumnsWithTypeAndName view_columns;
columns.reserve(key_columns.size());
for (const auto & key_column : key_columns)
{ {
ColumnPtr column = key_column.column->cut(start, length); Columns columns;
columns.emplace_back(column); ColumnsWithTypeAndName view_columns;
view_columns.emplace_back(column, key_column.type, key_column.name); columns.reserve(key_columns.size());
for (const auto & key_column : key_columns)
{
ColumnPtr column = key_column.column->cut(start, length);
columns.emplace_back(column);
view_columns.emplace_back(column, key_column.type, key_column.name);
}
return (this->*fillBlockFunction)({}, columns, {}, std::move(view_columns));
} }
return (this->*fillBlockFunction)({}, columns, {}, std::move(view_columns)); case DictionaryKeyType::Id:
}
else if (!ids.empty())
{
PaddedPODArray<Key> block_ids(ids.begin() + start, ids.begin() + start + length);
return (this->*fillBlockFunction)(block_ids, {}, {}, {});
}
else
{
Columns columns;
columns.reserve(data_columns.size());
for (const auto & data_column : data_columns)
columns.push_back(data_column->cut(start, length));
const DictionaryStructure & dictionaty_structure = dictionary->getStructure();
const auto & attributes = *dictionaty_structure.key;
ColumnsWithTypeAndName keys_with_type_and_name = get_key_columns_function(columns, attributes);
ColumnsWithTypeAndName view_with_type_and_name = get_view_columns_function(columns, attributes);
DataTypes types;
columns.clear();
for (const auto & key_column : keys_with_type_and_name)
{ {
columns.push_back(key_column.column); PaddedPODArray<Key> block_ids(ids.begin() + start, ids.begin() + start + length);
types.push_back(key_column.type); return (this->*fillBlockFunction)(block_ids, {}, {}, {});
}
case DictionaryKeyType::Callback:
{
Columns columns;
columns.reserve(data_columns.size());
for (const auto & data_column : data_columns)
columns.push_back(data_column->cut(start, length));
const DictionaryStructure & dictionaty_structure = dictionary->getStructure();
const auto & attributes = *dictionaty_structure.key;
ColumnsWithTypeAndName keys_with_type_and_name = get_key_columns_function(columns, attributes);
ColumnsWithTypeAndName view_with_type_and_name = get_view_columns_function(columns, attributes);
DataTypes types;
columns.clear();
for (const auto & key_column : keys_with_type_and_name)
{
columns.push_back(key_column.column);
types.push_back(key_column.type);
}
return (this->*fillBlockFunction)({}, columns, types, std::move(view_with_type_and_name));
} }
return (this->*fillBlockFunction)({}, columns, types, std::move(view_with_type_and_name));
} }
throw Exception("Unexpected DictionaryKeyType.", ErrorCodes::LOGICAL_ERROR);
} }
template <typename DictionaryType, typename Key> template <typename DictionaryType, typename Key>