mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-23 08:02:02 +00:00
Fix some rename cases
This commit is contained in:
parent
41ca7ae83a
commit
ab760846c2
@ -15,6 +15,7 @@ using NameSet = std::unordered_set<std::string>;
|
||||
using NameOrderedSet = std::set<std::string>;
|
||||
using NameToNameMap = std::unordered_map<std::string, std::string>;
|
||||
using NameToNameSetMap = std::unordered_map<std::string, NameSet>;
|
||||
using NameToNameVector = std::vector<std::pair<std::string, std::string>>;
|
||||
|
||||
using NameWithAlias = std::pair<std::string, std::string>;
|
||||
using NamesWithAliases = std::vector<NameWithAlias>;
|
||||
|
@ -733,7 +733,6 @@ 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)
|
||||
{
|
||||
const auto & command = (*this)[i];
|
||||
@ -809,31 +808,40 @@ void AlterCommands::validate(const StorageInMemoryMetadata & metadata, const Con
|
||||
}
|
||||
else if (command.type == AlterCommand::RENAME_COLUMN)
|
||||
{
|
||||
for (size_t j = i + 1; j < size(); ++j)
|
||||
{
|
||||
auto next_command = (*this)[j];
|
||||
if (next_command.type == AlterCommand::RENAME_COLUMN)
|
||||
{
|
||||
if (next_command.column_name == command.rename_to)
|
||||
throw Exception{"Transitive renames in a single ALTER query are not allowed (don't make sence)",
|
||||
ErrorCodes::NOT_IMPLEMENTED};
|
||||
else if (next_command.column_name == command.column_name)
|
||||
throw Exception{"Cannot rename column '" + backQuote(command.column_name)
|
||||
+ "' to two different names in a single ALTER query",
|
||||
ErrorCodes::BAD_ARGUMENTS};
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO Implement nested rename
|
||||
if (metadata.columns.hasNested(command.column_name))
|
||||
if (all_columns.hasNested(command.column_name))
|
||||
{
|
||||
throw Exception{"Cannot rename whole Nested struct", ErrorCodes::NOT_IMPLEMENTED};
|
||||
}
|
||||
|
||||
if (!metadata.columns.has(command.column_name))
|
||||
if (!all_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};
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if (metadata.columns.has(command.rename_to))
|
||||
if (all_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};
|
||||
|
||||
String from_nested_table_name = Nested::extractTableName(command.column_name);
|
||||
String to_nested_table_name = Nested::extractTableName(command.rename_to);
|
||||
bool from_nested = from_nested_table_name != command.column_name;
|
||||
@ -846,7 +854,7 @@ void AlterCommands::validate(const StorageInMemoryMetadata & metadata, const Con
|
||||
}
|
||||
else if (!from_nested && !to_nested)
|
||||
{
|
||||
renames_map[command.column_name] = command.rename_to;
|
||||
all_columns.rename(command.column_name, command.rename_to);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1085,7 +1085,7 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mutatePartToTempor
|
||||
auto indices_to_recalc = getIndicesToRecalculate(in, storage_from_source_part, updated_header.getNamesAndTypesList(), context);
|
||||
|
||||
NameSet files_to_skip = collectFilesToSkip(updated_header, indices_to_recalc, mrk_extension);
|
||||
NameToNameMap files_to_rename = collectFilesForRenames(source_part, for_file_renames, mrk_extension);
|
||||
NameToNameVector files_to_rename = collectFilesForRenames(source_part, for_file_renames, mrk_extension);
|
||||
|
||||
if (need_remove_expired_values)
|
||||
files_to_skip.insert("ttl.txt");
|
||||
@ -1097,7 +1097,8 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mutatePartToTempor
|
||||
continue;
|
||||
|
||||
String destination = new_part_tmp_path + "/";
|
||||
auto rename_it = files_to_rename.find(it->name());
|
||||
String file_name = it->name();
|
||||
auto rename_it = std::find_if(files_to_rename.begin(), files_to_rename.end(), [&file_name](const auto & rename_pair) { return rename_pair.first == file_name; });
|
||||
if (rename_it != files_to_rename.end())
|
||||
{
|
||||
if (rename_it->second.empty())
|
||||
@ -1328,7 +1329,7 @@ void MergeTreeDataMergerMutator::splitMutationCommands(
|
||||
}
|
||||
|
||||
|
||||
NameToNameMap MergeTreeDataMergerMutator::collectFilesForRenames(
|
||||
NameToNameVector MergeTreeDataMergerMutator::collectFilesForRenames(
|
||||
MergeTreeData::DataPartPtr source_part, const MutationCommands & commands_for_removes, const String & mrk_extension)
|
||||
{
|
||||
/// Collect counts for shared streams of different columns. As an example, Nested columns have shared stream with array sizes.
|
||||
@ -1343,14 +1344,14 @@ NameToNameMap MergeTreeDataMergerMutator::collectFilesForRenames(
|
||||
{});
|
||||
}
|
||||
|
||||
NameToNameMap rename_map;
|
||||
NameToNameVector rename_vector;
|
||||
/// Remove old indices
|
||||
for (const auto & command : commands_for_removes)
|
||||
{
|
||||
if (command.type == MutationCommand::Type::DROP_INDEX)
|
||||
{
|
||||
rename_map.emplace("skp_idx_" + command.column_name + ".idx", "");
|
||||
rename_map.emplace("skp_idx_" + command.column_name + mrk_extension, "");
|
||||
rename_vector.emplace_back("skp_idx_" + command.column_name + ".idx", "");
|
||||
rename_vector.emplace_back("skp_idx_" + command.column_name + mrk_extension, "");
|
||||
}
|
||||
else if (command.type == MutationCommand::Type::DROP_COLUMN)
|
||||
{
|
||||
@ -1360,8 +1361,8 @@ NameToNameMap MergeTreeDataMergerMutator::collectFilesForRenames(
|
||||
/// Delete files if they are no longer shared with another column.
|
||||
if (--stream_counts[stream_name] == 0)
|
||||
{
|
||||
rename_map.emplace(stream_name + ".bin", "");
|
||||
rename_map.emplace(stream_name + mrk_extension, "");
|
||||
rename_vector.emplace_back(stream_name + ".bin", "");
|
||||
rename_vector.emplace_back(stream_name + mrk_extension, "");
|
||||
}
|
||||
};
|
||||
|
||||
@ -1383,8 +1384,8 @@ NameToNameMap MergeTreeDataMergerMutator::collectFilesForRenames(
|
||||
|
||||
if (stream_from != stream_to)
|
||||
{
|
||||
rename_map.emplace(stream_from + ".bin", stream_to + ".bin");
|
||||
rename_map.emplace(stream_from + mrk_extension, stream_to + mrk_extension);
|
||||
rename_vector.emplace_back(stream_from + ".bin", stream_to + ".bin");
|
||||
rename_vector.emplace_back(stream_from + mrk_extension, stream_to + mrk_extension);
|
||||
}
|
||||
};
|
||||
IDataType::SubstreamPath stream_path;
|
||||
@ -1394,7 +1395,7 @@ NameToNameMap MergeTreeDataMergerMutator::collectFilesForRenames(
|
||||
}
|
||||
}
|
||||
|
||||
return rename_map;
|
||||
return rename_vector;
|
||||
}
|
||||
|
||||
NameSet MergeTreeDataMergerMutator::collectFilesToSkip(
|
||||
|
@ -143,10 +143,9 @@ private:
|
||||
MutationCommands & for_interpreter,
|
||||
MutationCommands & for_file_renames);
|
||||
|
||||
|
||||
/// Apply commands to source_part i.e. remove some columns in source_part
|
||||
/// and return set of files, that have to be removed from filesystem and checksums
|
||||
static NameToNameMap collectFilesForRenames(MergeTreeData::DataPartPtr source_part, const MutationCommands & commands_for_removes, const String & mrk_extension);
|
||||
static NameToNameVector collectFilesForRenames(MergeTreeData::DataPartPtr source_part, const MutationCommands & commands_for_removes, const String & mrk_extension);
|
||||
|
||||
/// Files, that we don't need to remove and don't need to hardlink, for example columns.txt and checksums.txt.
|
||||
/// Because we will generate new versions of them after we perform mutation.
|
||||
|
@ -24,7 +24,7 @@ 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 10}
|
||||
ALTER TABLE table_for_rename RENAME COLUMN value3 TO r1, RENAME COLUMN r1 TO value1; --{serverError 48}
|
||||
|
||||
ALTER TABLE table_for_rename RENAME COLUMN value2 TO renamed_value2, RENAME COLUMN value3 TO renamed_value3;
|
||||
|
||||
|
@ -0,0 +1,3 @@
|
||||
CREATE TABLE default.rename_table\n(\n `key` Int32, \n `old_value1` Int32, \n `value1` Int32\n)\nENGINE = MergeTree\nORDER BY tuple()\nSETTINGS index_granularity = 8192
|
||||
key old_value1 value1
|
||||
1 2 3
|
14
tests/queries/0_stateless/01278_alter_rename_combination.sql
Normal file
14
tests/queries/0_stateless/01278_alter_rename_combination.sql
Normal file
@ -0,0 +1,14 @@
|
||||
DROP TABLE IF EXISTS rename_table;
|
||||
|
||||
CREATE TABLE rename_table (key Int32, value1 Int32, value2 Int32) ENGINE = MergeTree ORDER BY tuple();
|
||||
|
||||
INSERT INTO rename_table VALUES (1, 2, 3);
|
||||
|
||||
-- replace one with other
|
||||
ALTER TABLE rename_table RENAME COLUMN value1 TO old_value1, RENAME COLUMN value2 TO value1;
|
||||
|
||||
SHOW CREATE TABLE rename_table;
|
||||
|
||||
SELECT * FROM rename_table FORMAT TSVWithNames;
|
||||
|
||||
DROP TABLE IF EXISTS rename_table;
|
Loading…
Reference in New Issue
Block a user