Add simple validation for renames

This commit is contained in:
alesapin 2020-03-30 16:34:19 +03:00
parent de0754ef0d
commit 8f91892d7b
3 changed files with 32 additions and 0 deletions

View File

@ -702,6 +702,7 @@ void AlterCommands::validate(const StorageInMemoryMetadata & metadata, const Con
auto all_columns = metadata.columns;
/// Default expression for all added/modified columns
ASTPtr default_expr_list = std::make_shared<ASTExpressionList>();
NameToNameMap renames_map;
for (size_t i = 0; i < size(); ++i)
{
auto & command = (*this)[i];
@ -775,6 +776,29 @@ void AlterCommands::validate(const StorageInMemoryMetadata & metadata, const Con
if (metadata.settings_ast == nullptr)
throw Exception{"Cannot alter settings, because table engine doesn't support settings changes", ErrorCodes::BAD_ARGUMENTS};
}
else if (command.type == AlterCommand::RENAME_COLUMN)
{
if (!metadata.columns.has(command.column_name))
{
if (!command.if_exists)
throw Exception{"Wrong column name. Cannot find column " + backQuote(command.column_name) + " to rename",
ErrorCodes::NOT_FOUND_COLUMN_IN_BLOCK};
}
if (metadata.columns.has(command.rename_to))
throw Exception{"Cannot rename to " + backQuote(command.rename_to) + ": column with this name already exists",
ErrorCodes::DUPLICATE_COLUMN};
if (renames_map.count(command.column_name))
throw Exception{"Cannot rename column '" + backQuote(command.column_name) + "' to two different names in a single ALTER query", ErrorCodes::BAD_ARGUMENTS};
if (renames_map.count(command.rename_to))
throw Exception{"Rename loop detected in ALTER query",
ErrorCodes::BAD_ARGUMENTS};
renames_map[command.column_name] = command.rename_to;
}
/// Collect default expressions for MODIFY and ADD comands
if (command.type == AlterCommand::MODIFY_COLUMN || command.type == AlterCommand::ADD_COLUMN)

View File

@ -1,2 +1,4 @@
1
1
date key renamed_value1 value2 value3
2019-10-02 1 1 1 1

View File

@ -20,4 +20,10 @@ ALTER TABLE table_for_rename RENAME COLUMN value1 to renamed_value1;
SELECT renamed_value1 FROM table_for_rename WHERE key = 1;
SELECT * FROM table_for_rename WHERE key = 1 FORMAT TSVWithNames;
ALTER TABLE table_for_rename RENAME COLUMN value3 to value2; --{serverError 15}
ALTER TABLE table_for_rename RENAME COLUMN value3 TO r1, RENAME COLUMN value3 TO r2; --{serverError 36}
ALTER TABLE table_for_rename RENAME COLUMN value3 TO r1, RENAME COLUMN r1 TO value1; --{serverError 36}
DROP TABLE IF EXISTS table_for_rename;