Fixed error with ALTER of Enums in Nested fields [#METR-22442].

This commit is contained in:
Alexey Milovidov 2016-11-20 11:57:11 +03:00
parent 37d6ecc372
commit c8c86208aa
3 changed files with 115 additions and 8 deletions

View File

@ -612,6 +612,9 @@ void MergeTreeData::createConvertExpression(const DataPartPtr & part, const Name
++nested_table_counts[DataTypeNested::extractNestedTableName(column.name)];
}
/// For every column that need to be converted: source column name, column name of calculated expression for conversion.
std::vector<std::pair<String, String>> conversions;
for (const NameAndTypePair & column : old_columns)
{
if (!new_types.count(column.name))
@ -669,21 +672,39 @@ void MergeTreeData::createConvertExpression(const DataPartPtr & part, const Name
{ std::make_shared<ColumnConstString>(1, new_type_name), std::make_shared<DataTypeString>(), new_type_name_column }));
const FunctionPtr & function = FunctionFactory::instance().get("CAST", context);
out_expression->add(ExpressionAction::applyFunction(function, Names{
column.name, new_type_name_column
}), out_names);
out_expression->add(ExpressionAction::applyFunction(
function, Names{column.name, new_type_name_column}), out_names);
out_expression->add(ExpressionAction::removeColumn(new_type_name_column));
out_expression->add(ExpressionAction::removeColumn(column.name));
const String escaped_expr = escapeForFileName(out_names[0]);
const String escaped_column = escapeForFileName(column.name);
out_rename_map[escaped_expr + ".bin"] = escaped_column + ".bin";
out_rename_map[escaped_expr + ".mrk"] = escaped_column + ".mrk";
conversions.emplace_back(column.name, out_names.at(0));
}
}
}
if (!conversions.empty())
{
/// Give proper names for temporary columns with conversion results.
NamesWithAliases projection;
projection.reserve(conversions.size());
for (const auto & source_and_expression : conversions)
{
String converting_column_name = source_and_expression.first + " converting";
projection.emplace_back(source_and_expression.second, converting_column_name);
const String escaped_converted_column = escapeForFileName(converting_column_name);
const String escaped_source_column = escapeForFileName(source_and_expression.first);
/// After conversion, we need to rename temporary files into original.
out_rename_map[escaped_converted_column + ".bin"] = escaped_source_column + ".bin";
out_rename_map[escaped_converted_column + ".mrk"] = escaped_source_column + ".mrk";
}
out_expression->add(ExpressionAction::project(projection));
}
}
MergeTreeData::AlterDataPartTransactionPtr MergeTreeData::alterDataPart(

View File

@ -0,0 +1,18 @@
2000-01-01 1 [''] ['Hello'] [0]
2000-01-01 1 [''] ['Hello'] [0]
2000-01-01 2 [''] ['World'] [0]
2000-01-01 1 [''] ['Hello'] [0]
2000-01-01 2 [''] ['World'] [0]
2000-01-01 1 [''] [1] [0]
2000-01-01 2 [''] [2] [0]
2000-01-01 1 [''] ['Hello'] [0]
2000-01-01 2 [''] ['World'] [0]
2000-01-01 1 [''] ['Hello'] [0]
2000-01-01 2 [''] ['World'] [0]
2000-01-01 1 [''] ['Hello'] [0]
2000-01-01 2 [''] ['World'] [0]
2000-01-01 1 ['system','rtb.client'] ['hello','world']
2000-01-01 1 ['system','rtb.client'] ['hello','world']
2000-01-01 2 ['http.status','http.code'] ['hello','goodbye']
2000-01-01 1 [''] ['Hello.world'] [0]
2000-01-01 1 [''] ['Hello.world'] [0]

View File

@ -0,0 +1,68 @@
DROP TABLE IF EXISTS test.enum_nested_alter;
CREATE TABLE test.enum_nested_alter
(d Date DEFAULT '2000-01-01', x UInt64, n Nested(a String, e Enum8('Hello' = 1), b UInt8))
ENGINE = MergeTree(d, x, 1);
INSERT INTO test.enum_nested_alter (x, n.e) VALUES (1, ['Hello']);
SELECT * FROM test.enum_nested_alter;
ALTER TABLE test.enum_nested_alter MODIFY COLUMN n.e Array(Enum8('Hello' = 1, 'World' = 2));
INSERT INTO test.enum_nested_alter (x, n.e) VALUES (2, ['World']);
SELECT * FROM test.enum_nested_alter ORDER BY x;
ALTER TABLE test.enum_nested_alter MODIFY COLUMN n.e Array(Enum16('Hello' = 1, 'World' = 2, 'a' = 300));
SELECT * FROM test.enum_nested_alter ORDER BY x;
ALTER TABLE test.enum_nested_alter MODIFY COLUMN n.e Array(UInt16);
SELECT * FROM test.enum_nested_alter ORDER BY x;
ALTER TABLE test.enum_nested_alter MODIFY COLUMN n.e Array(Enum16('Hello' = 1, 'World' = 2, 'a' = 300));
SELECT * FROM test.enum_nested_alter ORDER BY x;
ALTER TABLE test.enum_nested_alter MODIFY COLUMN n.e Array(String);
SELECT * FROM test.enum_nested_alter ORDER BY x;
ALTER TABLE test.enum_nested_alter MODIFY COLUMN n.e Array(Enum16('Hello' = 1, 'World' = 2, 'a' = 300));
SELECT * FROM test.enum_nested_alter ORDER BY x;
DROP TABLE test.enum_nested_alter;
CREATE TABLE test.enum_nested_alter
(
d Date DEFAULT '2000-01-01',
x UInt64,
tasks Nested(
errcategory Enum8(
'undefined' = 0, 'system' = 1, 'generic' = 2, 'asio.netdb' = 3, 'asio.misc' = 4,
'asio.addrinfo' = 5, 'rtb.client' = 6, 'rtb.logic' = 7, 'http.status' = 8),
status Enum16('hello' = 1, 'world' = 2)))
ENGINE = MergeTree(d, x, 1);
INSERT INTO test.enum_nested_alter (x, tasks.errcategory, tasks.status) VALUES (1, ['system', 'rtb.client'], ['hello', 'world']);
SELECT * FROM test.enum_nested_alter ORDER BY x;
ALTER TABLE test.enum_nested_alter
MODIFY COLUMN tasks.errcategory Array(Enum8(
'undefined' = 0, 'system' = 1, 'generic' = 2, 'asio.netdb' = 3, 'asio.misc' = 4,
'asio.addrinfo' = 5, 'rtb.client' = 6, 'rtb.logic' = 7, 'http.status' = 8, 'http.code' = 9)),
MODIFY COLUMN tasks.status Array(Enum8('hello' = 1, 'world' = 2, 'goodbye' = 3));
INSERT INTO test.enum_nested_alter (x, tasks.errcategory, tasks.status) VALUES (2, ['http.status', 'http.code'], ['hello', 'goodbye']);
SELECT * FROM test.enum_nested_alter ORDER BY x;
DROP TABLE test.enum_nested_alter;
DROP TABLE IF EXISTS test.enum_nested_alter;
CREATE TABLE test.enum_nested_alter
(d Date DEFAULT '2000-01-01', x UInt64, n Nested(a String, e Enum8('Hello.world' = 1), b UInt8))
ENGINE = MergeTree(d, x, 1);
INSERT INTO test.enum_nested_alter (x, n.e) VALUES (1, ['Hello.world']);
SELECT * FROM test.enum_nested_alter;
ALTER TABLE test.enum_nested_alter MODIFY COLUMN n.e Array(Enum8('Hello.world' = 1, 'a' = 2));
SELECT * FROM test.enum_nested_alter;
DROP TABLE test.enum_nested_alter;