#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace DB { namespace ErrorCodes { extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; extern const int BAD_ARGUMENTS; } DataTypeMap::DataTypeMap(const DataTypes & elems_) { assert(elems_.size() == 2); key_type = elems_[0]; value_type = elems_[1]; assertKeyType(); nested = std::make_shared( std::make_shared(DataTypes{key_type, value_type}, Names{"keys", "values"})); } DataTypeMap::DataTypeMap(const DataTypePtr & key_type_, const DataTypePtr & value_type_) : key_type(key_type_), value_type(value_type_) , nested(std::make_shared( std::make_shared(DataTypes{key_type_, value_type_}, Names{"keys", "values"}))) { assertKeyType(); } void DataTypeMap::assertKeyType() const { if (!key_type->isValueRepresentedByInteger() && !isStringOrFixedString(*key_type) && !WhichDataType(key_type).isNothing()) throw Exception(ErrorCodes::BAD_ARGUMENTS, "Type of Map key must be a type, that can be represented by integer or string," " but {} given", key_type->getName()); } std::string DataTypeMap::doGetName() const { WriteBufferFromOwnString s; s << "Map(" << key_type->getName() << "," << value_type->getName() << ")"; return s.str(); } static const IColumn & extractNestedColumn(const IColumn & column) { return assert_cast(column).getNestedColumn(); } DataTypePtr DataTypeMap::tryGetSubcolumnType(const String & subcolumn_name) const { return nested->tryGetSubcolumnType(subcolumn_name); } ColumnPtr DataTypeMap::getSubcolumn(const String & subcolumn_name, const IColumn & column) const { return nested->getSubcolumn(subcolumn_name, extractNestedColumn(column)); } SerializationPtr DataTypeMap::getSubcolumnSerialization( const String & subcolumn_name, const BaseSerializationGetter & base_serialization_getter) const { return nested->getSubcolumnSerialization(subcolumn_name, base_serialization_getter); } MutableColumnPtr DataTypeMap::createColumn() const { return ColumnMap::create(nested->createColumn()); } Field DataTypeMap::getDefault() const { return Map(); } SerializationPtr DataTypeMap::doGetDefaultSerialization() const { return std::make_shared( key_type->getDefaultSerialization(), value_type->getDefaultSerialization(), nested->getDefaultSerialization()); } bool DataTypeMap::equals(const IDataType & rhs) const { if (typeid(rhs) != typeid(*this)) return false; const DataTypeMap & rhs_map = static_cast(rhs); return nested->equals(*rhs_map.nested); } static DataTypePtr create(const ASTPtr & arguments) { if (!arguments || arguments->children.size() != 2) throw Exception("Map data type family must have two arguments: key and value types", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); DataTypes nested_types; nested_types.reserve(arguments->children.size()); for (const ASTPtr & child : arguments->children) nested_types.emplace_back(DataTypeFactory::instance().get(child)); return std::make_shared(nested_types); } void registerDataTypeMap(DataTypeFactory & factory) { factory.registerDataType("Map", create); } }