refine the interface

This commit is contained in:
jsc0218 2023-12-12 16:40:18 +00:00
parent af5eec0e5a
commit fdcd94bf5f
4 changed files with 168 additions and 14 deletions

View File

@ -151,6 +151,114 @@ ColumnPtr FlatDictionary::getColumn(
return result;
}
ColumnPtr FlatDictionary::getColumnOrDefault(
const std::string & attribute_name,
const DataTypePtr & result_type,
const Columns & key_columns,
const ColumnWithTypeAndName & default_argument) const
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-value"
attribute_name;result_type;key_columns;default_argument;
#pragma clang diagnostic pop
ColumnPtr result;
// PaddedPODArray<UInt64> backup_storage;
// const auto & ids = getColumnVectorData(this, key_columns.front(), backup_storage);
// auto size = ids.size();
// const auto & dictionary_attribute = dict_struct.getAttribute(attribute_name, result_type);
// size_t attribute_index = dict_struct.attribute_name_to_index.find(attribute_name)->second;
// const auto & attribute = attributes[attribute_index];
// bool is_attribute_nullable = attribute.is_nullable_set.has_value();
// ColumnUInt8::MutablePtr col_null_map_to;
// ColumnUInt8::Container * vec_null_map_to = nullptr;
// if (is_attribute_nullable)
// {
// col_null_map_to = ColumnUInt8::create(size, false);
// vec_null_map_to = &col_null_map_to->getData();
// }
// auto type_call = [&](const auto & dictionary_attribute_type)
// {
// using Type = std::decay_t<decltype(dictionary_attribute_type)>;
// using AttributeType = typename Type::AttributeType;
// using ValueType = DictionaryValueType<AttributeType>;
// using ColumnProvider = DictionaryAttributeColumnProvider<AttributeType>;
// DictionaryDefaultValueExtractor<AttributeType> default_value_extractor(dictionary_attribute.null_value, default_values_column);
// auto column = ColumnProvider::getColumn(dictionary_attribute, size);
// if constexpr (std::is_same_v<ValueType, Array>)
// {
// auto * out = column.get();
// getItemsImpl<ValueType, false>(
// attribute,
// ids,
// [&](size_t, const Array & value, bool) { out->insert(value); },
// default_value_extractor);
// }
// else if constexpr (std::is_same_v<ValueType, StringRef>)
// {
// auto * out = column.get();
// if (is_attribute_nullable)
// getItemsImpl<ValueType, true>(
// attribute,
// ids,
// [&](size_t row, StringRef value, bool is_null)
// {
// (*vec_null_map_to)[row] = is_null;
// out->insertData(value.data, value.size);
// },
// default_value_extractor);
// else
// getItemsImpl<ValueType, false>(
// attribute,
// ids,
// [&](size_t, StringRef value, bool) { out->insertData(value.data, value.size); },
// default_value_extractor);
// }
// else
// {
// auto & out = column->getData();
// if (is_attribute_nullable)
// getItemsImpl<ValueType, true>(
// attribute,
// ids,
// [&](size_t row, const auto value, bool is_null)
// {
// (*vec_null_map_to)[row] = is_null;
// out[row] = value;
// },
// default_value_extractor);
// else
// getItemsImpl<ValueType, false>(
// attribute,
// ids,
// [&](size_t row, const auto value, bool) { out[row] = value; },
// default_value_extractor);
// }
// result = std::move(column);
// };
// callOnDictionaryAttributeType(attribute.type, type_call);
// if (attribute.is_nullable_set)
// result = ColumnNullable::create(result, std::move(col_null_map_to));
return result;
}
ColumnUInt8::Ptr FlatDictionary::hasKeys(const Columns & key_columns, const DataTypes &) const
{
PaddedPODArray<UInt64> backup_storage;

View File

@ -76,12 +76,18 @@ public:
DictionaryKeyType getKeyType() const override { return DictionaryKeyType::Simple; }
ColumnPtr getColumn(
const std::string& attribute_name,
const std::string & attribute_name,
const DataTypePtr & result_type,
const Columns & key_columns,
const DataTypes & key_types,
const ColumnPtr & default_values_column) const override;
ColumnPtr getColumnOrDefault(
const std::string & attribute_name,
const DataTypePtr & result_type,
const Columns & key_columns,
const ColumnWithTypeAndName & default_argument) const override;
ColumnUInt8::Ptr hasKeys(const Columns & key_columns, const DataTypes & key_types) const override;
bool hasHierarchy() const override { return dict_struct.hierarchical_attribute_index.has_value(); }

View File

@ -252,6 +252,47 @@ public:
return result;
}
/**
* Analogous to getColumn, but for dictGetOrDefault
*/
virtual ColumnPtr getColumnOrDefault(
const std::string & attribute_name [[maybe_unused]],
const DataTypePtr & result_type [[maybe_unused]],
const Columns & key_columns [[maybe_unused]],
const ColumnWithTypeAndName & default_argument [[maybe_unused]]) const
{
throw Exception(ErrorCodes::NOT_IMPLEMENTED,
"Method getColumnOrDefault is not supported for {} dictionary.",
getDictionaryID().getNameForLogs());
}
/** Get multiple columns from dictionary.
*
* Default implementation just calls getColumnOrDefault multiple times.
* Subclasses can provide custom more efficient implementation.
*/
virtual Columns getColumnsOrDefault(
const Strings & attribute_names,
const DataTypes & result_types,
const Columns & key_columns,
const ColumnWithTypeAndName & default_argument) const
{
size_t attribute_names_size = attribute_names.size();
Columns result;
result.reserve(attribute_names_size);
for (size_t i = 0; i < attribute_names_size; ++i)
{
const auto & attribute_name = attribute_names[i];
const auto & result_type = result_types[i];
result.emplace_back(getColumnOrDefault(attribute_name, result_type,
key_columns, default_argument));
}
return result;
}
/** Subclass must validate key columns and key types and return ColumnUInt8 that
* is bitmask representation of is key in dictionary or not.
* If key is in dictionary then value of associated row will be 1, otherwise 0.

View File

@ -633,17 +633,16 @@ private:
result_columns = dictionary->getColumnsAllValues(
attribute_names, result_tuple_type.getElements(), key_columns, key_types, default_cols, collect_values_limit);
}
else if (dictionary_get_function_type == DictionaryGetFunctionType::getOrDefault && default_cols.front() == nullptr)
else if (dictionary_get_function_type == DictionaryGetFunctionType::getOrDefault
&& default_cols.front() == nullptr)
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-value"
last_argument;
#pragma clang diagnostic pop
result_columns = dictionary->getColumnsOrDefault(
attribute_names, result_tuple_type.getElements(), key_columns, last_argument);
}
else
{
result_columns
= dictionary->getColumns(attribute_names, result_tuple_type.getElements(), key_columns, key_types, default_cols);
result_columns = dictionary->getColumns(
attribute_names, result_tuple_type.getElements(), key_columns, key_types, default_cols);
}
result = ColumnTuple::create(std::move(result_columns));
@ -655,16 +654,16 @@ private:
result = dictionary->getColumnAllValues(
attribute_names[0], result_type, key_columns, key_types, default_cols.front(), collect_values_limit);
}
else if (dictionary_get_function_type == DictionaryGetFunctionType::getOrDefault && default_cols.front() == nullptr)
else if (dictionary_get_function_type == DictionaryGetFunctionType::getOrDefault
&& default_cols.front() == nullptr)
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-value"
last_argument;
#pragma clang diagnostic pop
result = dictionary->getColumnOrDefault(
attribute_names[0], result_type, key_columns, last_argument);
}
else
{
result = dictionary->getColumn(attribute_names[0], result_type, key_columns, key_types, default_cols.front());
result = dictionary->getColumn(
attribute_names[0], result_type, key_columns, key_types, default_cols.front());
}
}