Make more alters of nested types metadata-only

This commit is contained in:
alesapin 2022-04-03 14:03:34 +02:00
parent 91453fe4d6
commit 7b35920d4c
3 changed files with 55 additions and 12 deletions

View File

@ -696,20 +696,22 @@ namespace
/// The function works for Arrays and Nullables of the same structure.
bool isMetadataOnlyConversion(const IDataType * from, const IDataType * to)
{
if (from->equals(*to))
return true;
if (const auto * from_enum8 = typeid_cast<const DataTypeEnum8 *>(from))
auto is_compatible_enum_types_conversion = [](const IDataType * from_type, const IDataType * to_type)
{
if (const auto * to_enum8 = typeid_cast<const DataTypeEnum8 *>(to))
return to_enum8->contains(*from_enum8);
}
if (const auto * from_enum8 = typeid_cast<const DataTypeEnum8 *>(from_type))
{
if (const auto * to_enum8 = typeid_cast<const DataTypeEnum8 *>(to_type))
return to_enum8->contains(*from_enum8);
}
if (const auto * from_enum16 = typeid_cast<const DataTypeEnum16 *>(from))
{
if (const auto * to_enum16 = typeid_cast<const DataTypeEnum16 *>(to))
return to_enum16->contains(*from_enum16);
}
if (const auto * from_enum16 = typeid_cast<const DataTypeEnum16 *>(from_type))
{
if (const auto * to_enum16 = typeid_cast<const DataTypeEnum16 *>(to_type))
return to_enum16->contains(*from_enum16);
}
return false;
};
static const std::unordered_multimap<std::type_index, const std::type_info &> ALLOWED_CONVERSIONS =
{
@ -721,11 +723,18 @@ bool isMetadataOnlyConversion(const IDataType * from, const IDataType * to)
{ typeid(DataTypeUInt16), typeid(DataTypeDate) },
};
/// Unwrap some nested and check for valid conevrsions
while (true)
{
/// types are equal, obviously pure metadata alter
if (from->equals(*to))
return true;
/// We just adding something to enum, nothing changed on disk
if (is_compatible_enum_types_conversion(from, to))
return true;
/// Types changed, but representation on disk didn't
auto it_range = ALLOWED_CONVERSIONS.equal_range(typeid(*from));
for (auto it = it_range.first; it != it_range.second; ++it)
{

View File

@ -0,0 +1,7 @@
1 ['Option2','Option1']
2 ['Option1']
3 ['Option1','Option3']
1 ['Option2','Option1']
2 ['Option1']
3 ['Option1','Option3']
0

View File

@ -0,0 +1,27 @@
DROP TABLE IF EXISTS alter_enum_array;
CREATE TABLE alter_enum_array(
Key UInt64,
Value Array(Enum8('Option1'=1, 'Option2'=2))
)
ENGINE=MergeTree()
ORDER BY tuple();
INSERT INTO alter_enum_array VALUES (1, ['Option2', 'Option1']), (2, ['Option1']);
ALTER TABLE alter_enum_array MODIFY COLUMN Value Array(Enum8('Option1'=1, 'Option2'=2, 'Option3'=3)) SETTINGS mutations_sync=2;
INSERT INTO alter_enum_array VALUES (3, ['Option1','Option3']);
SELECT * FROM alter_enum_array ORDER BY Key;
DETACH TABLE alter_enum_array;
ATTACH TABLE alter_enum_array;
SELECT * FROM alter_enum_array ORDER BY Key;
OPTIMIZE TABLE alter_enum_array FINAL;
SELECT COUNT() FROM system.mutations where table='alter_enum_array' and database=currentDatabase();
DROP TABLE IF EXISTS alter_enum_array;