Fixes #26672. Lower restrictions in StorageInMemoryMetadata::check.

This commit is contained in:
Dmitry Novik 2021-08-23 16:08:23 +03:00
parent 9ef45d92c2
commit ac2e9a27e6
6 changed files with 43 additions and 3 deletions

View File

@ -27,6 +27,8 @@ public:
bool isCategorial() const override { return true; }
bool canBeInsideNullable() const override { return true; }
bool isComparable() const override { return true; }
virtual bool contains(const IDataType & rhs) const = 0;
};
@ -76,7 +78,7 @@ public:
/// Example:
/// Enum('a' = 1, 'b' = 2) -> Enum('c' = 1, 'b' = 2, 'd' = 3) OK
/// Enum('a' = 1, 'b' = 2) -> Enum('a' = 2, 'b' = 1) NOT OK
bool contains(const IDataType & rhs) const;
virtual bool contains(const IDataType & rhs) const override;
SerializationPtr doGetDefaultSerialization() const override;
};

View File

@ -5,6 +5,7 @@
#include <Common/quoteString.h>
#include <Common/StringUtils/StringUtils.h>
#include <Core/ColumnWithTypeAndName.h>
#include <DataTypes/DataTypeEnum.h>
#include <IO/ReadBufferFromString.h>
#include <IO/ReadHelpers.h>
#include <IO/Operators.h>
@ -493,6 +494,15 @@ namespace
return res;
}
bool isEnumSubset(const IDataType* lhs, const DataTypePtr& rhs)
{
const WhichDataType & which = WhichDataType{lhs};
if (!which.isEnum())
return false;
IDataTypeEnum const* enum_type = dynamic_cast<IDataTypeEnum const*>(lhs);
return enum_type->contains(*rhs);
}
}
void StorageInMemoryMetadata::check(const Names & column_names, const NamesAndTypesList & virtuals, const StorageID & storage_id) const
@ -544,12 +554,13 @@ void StorageInMemoryMetadata::check(const NamesAndTypesList & provided_columns)
column.name,
listOfColumns(available_columns));
if (!column.type->equals(*it->getMapped()))
auto const mappedType = it->getMapped();
if (!column.type->equals(*mappedType) && !isEnumSubset(mappedType, column.type))
throw Exception(
ErrorCodes::TYPE_MISMATCH,
"Type mismatch for column {}. Column has type {}, got type {}",
column.name,
it->getMapped()->getName(),
mappedType->getName(),
column.type->getName());
if (unique_names.end() != unique_names.find(column.name))

View File

@ -0,0 +1,2 @@
one
two

View File

@ -0,0 +1,13 @@
create table enum_alter_issue (a Enum8('one' = 1, 'two' = 2))
engine = ReplicatedMergeTree('/clickhouse/tables/{database}/test_02012/enum_alter_issue', 'r1')
ORDER BY a;
insert into enum_alter_issue values ('one'), ('two');
alter table enum_alter_issue modify column a Enum8('one' = 1, 'two' = 2, 'three' = 3);
insert into enum_alter_issue values ('one'), ('two');
alter table enum_alter_issue detach partition id 'all';
alter table enum_alter_issue attach partition id 'all';
select * from enum_alter_issue;
drop table enum_alter_issue;

View File

@ -0,0 +1,4 @@
one
two
one
two

View File

@ -0,0 +1,8 @@
create table enum_alter_issue (a Enum8('one' = 1, 'two' = 2)) engine = MergeTree() ORDER BY a;
insert into enum_alter_issue values ('one'), ('two');
alter table enum_alter_issue modify column a Enum8('one' = 1, 'two' = 2, 'three' = 3);
insert into enum_alter_issue values ('one'), ('two');
alter table enum_alter_issue detach partition id 'all';
alter table enum_alter_issue attach partition id 'all';
select * from enum_alter_issue;
drop table enum_alter_issue;