@@ -4018,6 +4018,11 @@ void MergeTreeData::checkAlterIsPossible(const AlterCommands & commands, Context
40184018 // / Columns to check that the type change is safe for partition key.
40194019 NameSet columns_alter_type_check_safe_for_partition;
40204020
4021+ // / Columns with subcolumns used in primary key or partition key.
4022+ std::unordered_map<String, std::vector<String>> column_to_subcolumns_used_in_keys;
4023+
4024+ const auto & old_columns = old_metadata.getColumns ();
4025+
40214026 if (old_metadata.hasPartitionKey ())
40224027 {
40234028 // / Forbid altering columns inside partition key expressions because it can change partition ID format.
@@ -4030,7 +4035,13 @@ void MergeTreeData::checkAlterIsPossible(const AlterCommands & commands, Context
40304035
40314036 // / But allow to alter columns without expressions under certain condition.
40324037 for (const String & col : partition_key_expr->getRequiredColumns ())
4033- columns_alter_type_check_safe_for_partition.insert (col);
4038+ {
4039+ auto storage_column = old_columns.tryGetColumnOrSubcolumn (GetColumnsOptions::All, col);
4040+ if (storage_column && storage_column->isSubcolumn ())
4041+ column_to_subcolumns_used_in_keys[storage_column->getNameInStorage ()].push_back (backQuoteIfNeed (col));
4042+ else
4043+ columns_alter_type_check_safe_for_partition.insert (col);
4044+ }
40344045 }
40354046
40364047 if (old_metadata.hasSortingKey ())
@@ -4042,7 +4053,13 @@ void MergeTreeData::checkAlterIsPossible(const AlterCommands & commands, Context
40424053 columns_alter_type_forbidden.insert (child->result_name );
40434054 }
40444055 for (const String & col : sorting_key_expr->getRequiredColumns ())
4045- columns_alter_type_metadata_only.insert (col);
4056+ {
4057+ auto storage_column = old_columns.tryGetColumnOrSubcolumn (GetColumnsOptions::All, col);
4058+ if (storage_column && storage_column->isSubcolumn ())
4059+ column_to_subcolumns_used_in_keys[storage_column->getNameInStorage ()].push_back (backQuoteIfNeed (col));
4060+ else
4061+ columns_alter_type_metadata_only.insert (col);
4062+ }
40464063
40474064 // / We don't process sample_by_ast separately because it must be among the primary key columns
40484065 // / and we don't process primary_key_expr separately because it is a prefix of sorting_key_expr.
@@ -4172,6 +4189,15 @@ void MergeTreeData::checkAlterIsPossible(const AlterCommands & commands, Context
41724189 backQuoteIfNeed (command.column_name ));
41734190 }
41744191
4192+ if (column_to_subcolumns_used_in_keys.contains (command.column_name ))
4193+ {
4194+ throw Exception (
4195+ ErrorCodes::ALTER_OF_COLUMN_IS_FORBIDDEN,
4196+ " Trying to ALTER RENAME column {} whose subcolumns ({}) are part of key expression" ,
4197+ backQuoteIfNeed (command.column_name ),
4198+ boost::join (column_to_subcolumns_used_in_keys[command.column_name ], " , " ));
4199+ }
4200+
41754201 // / Don't check columns in indices here. RENAME works fine with index columns.
41764202
41774203 if (auto it = columns_in_projections.find (command.column_name ); it != columns_in_projections.end ())
@@ -4191,6 +4217,15 @@ void MergeTreeData::checkAlterIsPossible(const AlterCommands & commands, Context
41914217 " Trying to ALTER DROP key {} column which is a part of key expression" , backQuoteIfNeed (command.column_name ));
41924218 }
41934219
4220+ if (column_to_subcolumns_used_in_keys.contains (command.column_name ))
4221+ {
4222+ throw Exception (
4223+ ErrorCodes::ALTER_OF_COLUMN_IS_FORBIDDEN,
4224+ " Trying to ALTER DROP column {} whose subcolumns ({}) are part of key expression" ,
4225+ backQuoteIfNeed (command.column_name ),
4226+ boost::join (column_to_subcolumns_used_in_keys[command.column_name ], " , " ));
4227+ }
4228+
41944229 // / Don't check columns in indices or projections here. If required columns of indices
41954230 // / or projections get dropped, it will be checked later in AlterCommands::apply. This
41964231 // / allows projections with * to drop columns. One example can be found in
@@ -4239,6 +4274,15 @@ void MergeTreeData::checkAlterIsPossible(const AlterCommands & commands, Context
42394274 throw Exception (ErrorCodes::ALTER_OF_COLUMN_IS_FORBIDDEN, " ALTER of key column {} is forbidden" ,
42404275 backQuoteIfNeed (command.column_name ));
42414276
4277+ if (column_to_subcolumns_used_in_keys.contains (command.column_name ))
4278+ {
4279+ throw Exception (
4280+ ErrorCodes::ALTER_OF_COLUMN_IS_FORBIDDEN,
4281+ " Trying to ALTER column {} whose subcolumns ({}) are part of key expression" ,
4282+ backQuoteIfNeed (command.column_name ),
4283+ boost::join (column_to_subcolumns_used_in_keys[command.column_name ], " , " ));
4284+ }
4285+
42424286 if (auto it = columns_in_indices.find (command.column_name ); it != columns_in_indices.end ())
42434287 {
42444288 throw Exception (
0 commit comments