diff --git a/dbms/src/Dictionaries/PolygonDictionary.cpp b/dbms/src/Dictionaries/PolygonDictionary.cpp index 064e8e428bc..758cfcef2b6 100644 --- a/dbms/src/Dictionaries/PolygonDictionary.cpp +++ b/dbms/src/Dictionaries/PolygonDictionary.cpp @@ -94,13 +94,74 @@ BlockInputStreamPtr IPolygonDictionary::getBlockInputStream(const Names &, size_ throw Exception{"Reading the dictionary is not allowed", ErrorCodes::UNSUPPORTED_METHOD}; } +template +void IPolygonDictionary::appendNullValueImpl(const Field & null_value) +{ + null_values.emplace_back(T(null_value.get>())); +} + +void IPolygonDictionary::appendNullValue(AttributeUnderlyingType type, const Field & null_value) +{ + switch (type) + { + case AttributeUnderlyingType::utUInt8: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utUInt16: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utUInt32: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utUInt64: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utUInt128: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utInt8: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utInt16: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utInt32: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utInt64: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utFloat32: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utFloat64: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utDecimal32: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utDecimal64: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utDecimal128: + appendNullValueImpl(null_value); + break; + case AttributeUnderlyingType::utString: + appendNullValueImpl(null_value); + break; + } +} + void IPolygonDictionary::createAttributes() { attributes.resize(dict_struct.attributes.size()); for (size_t i = 0; i < dict_struct.attributes.size(); ++i) { - attribute_index_by_name.emplace(dict_struct.attributes[i].name, i); + const auto & attr = dict_struct.attributes[i]; + attribute_index_by_name.emplace(attr.name, i); - if (dict_struct.attributes[i].hierarchical) + appendNullValue(attr.underlying_type, attr.null_value); + + if (attr.hierarchical) throw Exception{name + ": hierarchical attributes not supported for dictionary of type " + getTypeName(), ErrorCodes::TYPE_MISMATCH}; } @@ -186,12 +247,6 @@ size_t IPolygonDictionary::getAttributeIndex(const std::string & attribute_name) return it->second; } -template -T IPolygonDictionary::getNullValue(const DB::Field &field) -{ - return field.get>(); -} - #define DECLARE(TYPE) \ void IPolygonDictionary::get##TYPE( \ const std::string & attribute_name, const Columns & key_columns, const DataTypes &, ResultArrayType & out) const \ @@ -199,7 +254,7 @@ T IPolygonDictionary::getNullValue(const DB::Field &field) const auto ind = getAttributeIndex(attribute_name); \ checkAttributeType(name, attribute_name, dict_struct.attributes[ind].underlying_type, AttributeUnderlyingType::ut##TYPE); \ \ - const auto null_value = getNullValue(dict_struct.attributes[ind].null_value); \ + const auto null_value = std::get(null_values[ind]); \ \ getItemsImpl( \ ind, \ @@ -229,7 +284,7 @@ void IPolygonDictionary::getString( const auto ind = getAttributeIndex(attribute_name); checkAttributeType(name, attribute_name, dict_struct.attributes[ind].underlying_type, AttributeUnderlyingType::utString); - const auto & null_value = getNullValue(dict_struct.attributes[ind].null_value); + const auto & null_value = StringRef{std::get(null_values[ind])}; getItemsImpl( ind, @@ -352,8 +407,7 @@ void IPolygonDictionary::getItemsImpl( const auto found = find(points[i], id); if (!found) { - const auto def = get_default(i); - set_value(i, static_cast(def)); + set_value(i, static_cast(get_default(i))); continue; } if constexpr (std::is_same::value) diff --git a/dbms/src/Dictionaries/PolygonDictionary.h b/dbms/src/Dictionaries/PolygonDictionary.h index 54678d86b90..c16b4e4d752 100644 --- a/dbms/src/Dictionaries/PolygonDictionary.h +++ b/dbms/src/Dictionaries/PolygonDictionary.h @@ -186,9 +186,9 @@ private: /** Checks whether a given attribute exists and returns its index */ size_t getAttributeIndex(const std::string & attribute_name) const; - /** Return the default type T value of field. */ template - static T getNullValue(const Field & field); + void appendNullValueImpl(const Field & null_value); + void appendNullValue(AttributeUnderlyingType type, const Field & value); /** Helper function for retrieving the value of an attribute by key. */ template @@ -196,6 +196,22 @@ private: std::map attribute_index_by_name; Columns attributes; + std::vector> null_values; size_t bytes_allocated = 0; size_t element_count = 0;