2017-04-01 09:19:00 +00:00
# include <Interpreters/InterpreterAlterQuery.h>
2017-04-25 15:21:03 +00:00
# include <Interpreters/DDLWorker.h>
2017-04-01 09:19:00 +00:00
# include <Parsers/ASTAlterQuery.h>
# include <Parsers/ASTCreateQuery.h>
# include <Parsers/ASTExpressionList.h>
# include <Parsers/ASTNameTypePair.h>
# include <Parsers/ASTIdentifier.h>
# include <Parsers/ASTLiteral.h>
# include <Parsers/ParserCreateQuery.h>
# include <IO/copyData.h>
# include <IO/ReadBufferFromFile.h>
# include <Common/escapeForFileName.h>
# include <DataTypes/DataTypeFactory.h>
# include <Parsers/formatAST.h>
# include <Parsers/parseQuery.h>
2013-08-07 13:07:42 +00:00
2014-06-03 23:09:57 +00:00
# include <Poco/FileStream.h>
2013-08-07 13:07:42 +00:00
# include <algorithm>
2013-08-09 00:12:59 +00:00
2016-01-11 21:46:36 +00:00
namespace DB
{
namespace ErrorCodes
{
2017-04-01 07:20:54 +00:00
extern const int LOGICAL_ERROR ;
extern const int ARGUMENT_OUT_OF_BOUND ;
2017-06-22 11:01:30 +00:00
extern const int BAD_ARGUMENTS ;
2017-07-14 18:09:28 +00:00
extern const int ILLEGAL_COLUMN ;
2016-01-11 21:46:36 +00:00
}
2013-09-23 12:01:19 +00:00
2017-05-23 18:01:50 +00:00
InterpreterAlterQuery : : InterpreterAlterQuery ( const ASTPtr & query_ptr_ , const Context & context_ )
2017-04-01 07:20:54 +00:00
: query_ptr ( query_ptr_ ) , context ( context_ )
2013-08-07 13:07:42 +00:00
{
}
2015-06-18 02:11:05 +00:00
BlockIO InterpreterAlterQuery : : execute ( )
2013-12-18 11:19:37 +00:00
{
2017-04-01 07:20:54 +00:00
auto & alter = typeid_cast < ASTAlterQuery & > ( * query_ptr ) ;
2017-04-25 15:21:03 +00:00
if ( ! alter . cluster . empty ( ) )
2018-04-17 19:33:58 +00:00
return executeDDLQueryOnCluster ( query_ptr , context , { alter . table } ) ;
2017-04-25 15:21:03 +00:00
2017-04-01 07:20:54 +00:00
const String & table_name = alter . table ;
String database_name = alter . database . empty ( ) ? context . getCurrentDatabase ( ) : alter . database ;
StoragePtr table = context . getTable ( database_name , table_name ) ;
AlterCommands alter_commands ;
PartitionCommands partition_commands ;
2018-02-02 16:02:43 +00:00
MutationCommands mutation_commands ;
2018-06-09 15:53:14 +00:00
parseAlter ( alter . command_list - > commands , alter_commands , partition_commands , mutation_commands ) ;
2018-02-02 16:02:43 +00:00
if ( ! mutation_commands . commands . empty ( ) )
{
2018-05-15 12:56:14 +00:00
mutation_commands . validate ( * table , context ) ;
2018-02-02 16:02:43 +00:00
table - > mutate ( mutation_commands , context ) ;
}
2017-04-01 07:20:54 +00:00
2018-05-15 12:56:14 +00:00
partition_commands . validate ( * table ) ;
2017-04-01 07:20:54 +00:00
for ( const PartitionCommand & command : partition_commands )
{
switch ( command . type )
{
case PartitionCommand : : DROP_PARTITION :
2017-09-06 20:34:26 +00:00
table - > dropPartition ( query_ptr , command . partition , command . detach , context ) ;
2017-04-01 07:20:54 +00:00
break ;
case PartitionCommand : : ATTACH_PARTITION :
2017-09-06 20:34:26 +00:00
table - > attachPartition ( command . partition , command . part , context ) ;
2017-04-01 07:20:54 +00:00
break ;
2018-05-21 13:49:54 +00:00
case PartitionCommand : : REPLACE_PARTITION :
{
String from_database = command . from_database . empty ( ) ? context . getCurrentDatabase ( ) : command . from_database ;
auto from_storage = context . getTable ( from_database , command . from_table ) ;
table - > replacePartitionFrom ( from_storage , command . partition , command . replace , context ) ;
}
break ;
2017-04-01 07:20:54 +00:00
case PartitionCommand : : FETCH_PARTITION :
2018-05-21 13:49:54 +00:00
table - > fetchPartition ( command . partition , command . from_zookeeper_path , context ) ;
2017-04-01 07:20:54 +00:00
break ;
case PartitionCommand : : FREEZE_PARTITION :
2017-09-06 20:34:26 +00:00
table - > freezePartition ( command . partition , command . with_name , context ) ;
2017-04-01 07:20:54 +00:00
break ;
2017-06-22 11:01:30 +00:00
case PartitionCommand : : CLEAR_COLUMN :
2017-09-06 20:34:26 +00:00
table - > clearColumnInPartition ( command . partition , command . column_name , context ) ;
2017-04-14 12:40:48 +00:00
break ;
2017-04-01 07:20:54 +00:00
}
}
2018-02-02 16:02:43 +00:00
if ( ! alter_commands . empty ( ) )
{
2018-05-15 12:56:14 +00:00
alter_commands . validate ( * table , context ) ;
2018-02-02 16:02:43 +00:00
table - > alter ( alter_commands , database_name , table_name , context ) ;
}
2017-04-01 07:20:54 +00:00
return { } ;
2013-12-18 11:19:37 +00:00
}
2014-08-06 10:26:35 +00:00
void InterpreterAlterQuery : : parseAlter (
2018-06-09 15:53:14 +00:00
const std : : vector < ASTAlterCommand * > & command_asts ,
2018-02-02 16:02:43 +00:00
AlterCommands & out_alter_commands ,
PartitionCommands & out_partition_commands ,
MutationCommands & out_mutation_commands )
2014-04-02 18:53:30 +00:00
{
2017-04-01 07:20:54 +00:00
const DataTypeFactory & data_type_factory = DataTypeFactory : : instance ( ) ;
2018-06-09 15:53:14 +00:00
for ( const auto & command_ast : command_asts )
2017-04-01 07:20:54 +00:00
{
2018-06-09 15:53:14 +00:00
if ( command_ast - > type = = ASTAlterCommand : : ADD_COLUMN )
2017-04-01 07:20:54 +00:00
{
AlterCommand command ;
command . type = AlterCommand : : ADD_COLUMN ;
2018-06-09 15:53:14 +00:00
const auto & ast_col_decl = typeid_cast < const ASTColumnDeclaration & > ( * command_ast - > col_decl ) ;
2017-04-01 07:20:54 +00:00
command . column_name = ast_col_decl . name ;
if ( ast_col_decl . type )
{
2018-02-26 03:37:08 +00:00
command . data_type = data_type_factory . get ( ast_col_decl . type ) ;
2017-04-01 07:20:54 +00:00
}
if ( ast_col_decl . default_expression )
{
2018-03-12 13:47:01 +00:00
command . default_kind = columnDefaultKindFromString ( ast_col_decl . default_specifier ) ;
2017-04-01 07:20:54 +00:00
command . default_expression = ast_col_decl . default_expression ;
}
2018-06-09 15:53:14 +00:00
if ( command_ast - > column )
command . after_column = typeid_cast < const ASTIdentifier & > ( * command_ast - > column ) . name ;
2017-04-01 07:20:54 +00:00
out_alter_commands . emplace_back ( std : : move ( command ) ) ;
}
2018-06-09 15:53:14 +00:00
else if ( command_ast - > type = = ASTAlterCommand : : DROP_COLUMN )
2017-04-01 07:20:54 +00:00
{
2018-06-09 15:53:14 +00:00
if ( command_ast - > partition )
2017-04-14 12:40:48 +00:00
{
2018-06-09 15:53:14 +00:00
if ( ! command_ast - > clear_column )
2017-06-22 11:01:30 +00:00
throw Exception ( " Can't DROP COLUMN from partition. It is possible only CLEAR COLUMN in partition " , ErrorCodes : : BAD_ARGUMENTS ) ;
2018-06-09 15:53:14 +00:00
const Field & column_name = typeid_cast < const ASTIdentifier & > ( * ( command_ast - > column ) ) . name ;
2017-04-01 07:20:54 +00:00
2018-06-09 15:53:14 +00:00
out_partition_commands . emplace_back ( PartitionCommand : : clearColumn ( command_ast - > partition , column_name ) ) ;
2017-04-14 12:40:48 +00:00
}
else
{
2018-06-09 15:53:14 +00:00
if ( command_ast - > clear_column )
2017-06-22 11:01:30 +00:00
throw Exception ( " \" ALTER TABLE table CLEAR COLUMN column \" queries are not supported yet. Use \" CLEAR COLUMN column IN PARTITION \" . " , ErrorCodes : : NOT_IMPLEMENTED ) ;
2017-04-14 12:40:48 +00:00
AlterCommand command ;
command . type = AlterCommand : : DROP_COLUMN ;
2018-06-09 15:53:14 +00:00
command . column_name = typeid_cast < const ASTIdentifier & > ( * ( command_ast - > column ) ) . name ;
2017-04-14 12:40:48 +00:00
out_alter_commands . emplace_back ( std : : move ( command ) ) ;
}
2017-04-01 07:20:54 +00:00
}
2018-06-09 15:53:14 +00:00
else if ( command_ast - > type = = ASTAlterCommand : : MODIFY_COLUMN )
2017-04-01 07:20:54 +00:00
{
AlterCommand command ;
command . type = AlterCommand : : MODIFY_COLUMN ;
2018-06-09 15:53:14 +00:00
const auto & ast_col_decl = typeid_cast < const ASTColumnDeclaration & > ( * command_ast - > col_decl ) ;
2017-04-01 07:20:54 +00:00
command . column_name = ast_col_decl . name ;
if ( ast_col_decl . type )
{
2018-02-26 03:37:08 +00:00
command . data_type = data_type_factory . get ( ast_col_decl . type ) ;
2017-04-01 07:20:54 +00:00
}
if ( ast_col_decl . default_expression )
{
2018-03-12 13:47:01 +00:00
command . default_kind = columnDefaultKindFromString ( ast_col_decl . default_specifier ) ;
2017-04-01 07:20:54 +00:00
command . default_expression = ast_col_decl . default_expression ;
}
out_alter_commands . emplace_back ( std : : move ( command ) ) ;
}
2018-06-09 15:53:14 +00:00
else if ( command_ast - > type = = ASTAlterCommand : : MODIFY_PRIMARY_KEY )
2017-04-01 07:20:54 +00:00
{
AlterCommand command ;
command . type = AlterCommand : : MODIFY_PRIMARY_KEY ;
2018-06-09 15:53:14 +00:00
command . primary_key = command_ast - > primary_key ;
2017-04-01 07:20:54 +00:00
out_alter_commands . emplace_back ( std : : move ( command ) ) ;
}
2018-06-09 15:53:14 +00:00
else if ( command_ast - > type = = ASTAlterCommand : : DROP_PARTITION )
2017-04-01 07:20:54 +00:00
{
2018-06-09 15:53:14 +00:00
out_partition_commands . emplace_back ( PartitionCommand : : dropPartition ( command_ast - > partition , command_ast - > detach ) ) ;
2017-04-01 07:20:54 +00:00
}
2018-06-09 15:53:14 +00:00
else if ( command_ast - > type = = ASTAlterCommand : : ATTACH_PARTITION )
2017-04-01 07:20:54 +00:00
{
2018-06-09 15:53:14 +00:00
out_partition_commands . emplace_back ( PartitionCommand : : attachPartition ( command_ast - > partition , command_ast - > part ) ) ;
2017-04-01 07:20:54 +00:00
}
2018-06-09 15:53:14 +00:00
else if ( command_ast - > type = = ASTAlterCommand : : REPLACE_PARTITION )
2018-05-21 13:49:54 +00:00
{
out_partition_commands . emplace_back (
2018-06-09 15:53:14 +00:00
PartitionCommand : : replacePartition ( command_ast - > partition , command_ast - > replace , command_ast - > from_database , command_ast - > from_table ) ) ;
2018-05-21 13:49:54 +00:00
}
2018-06-09 15:53:14 +00:00
else if ( command_ast - > type = = ASTAlterCommand : : FETCH_PARTITION )
2017-04-01 07:20:54 +00:00
{
2018-06-09 15:53:14 +00:00
out_partition_commands . emplace_back ( PartitionCommand : : fetchPartition ( command_ast - > partition , command_ast - > from ) ) ;
2017-04-01 07:20:54 +00:00
}
2018-06-09 15:53:14 +00:00
else if ( command_ast - > type = = ASTAlterCommand : : FREEZE_PARTITION )
2017-04-01 07:20:54 +00:00
{
2018-06-09 15:53:14 +00:00
out_partition_commands . emplace_back ( PartitionCommand : : freezePartition ( command_ast - > partition , command_ast - > with_name ) ) ;
2017-04-01 07:20:54 +00:00
}
2018-06-09 15:53:14 +00:00
else if ( command_ast - > type = = ASTAlterCommand : : DELETE )
2018-02-02 16:02:43 +00:00
{
2018-06-09 15:53:14 +00:00
out_mutation_commands . commands . emplace_back ( MutationCommand : : delete_ ( command_ast - > predicate ) ) ;
2018-02-02 16:02:43 +00:00
}
2017-04-01 07:20:54 +00:00
else
throw Exception ( " Wrong parameter type in ALTER query " , ErrorCodes : : LOGICAL_ERROR ) ;
}
2014-05-20 15:00:13 +00:00
}
2017-07-14 18:09:28 +00:00
2018-05-15 12:56:14 +00:00
void InterpreterAlterQuery : : PartitionCommands : : validate ( const IStorage & table )
2017-07-14 18:09:28 +00:00
{
for ( const PartitionCommand & command : * this )
{
if ( command . type = = PartitionCommand : : CLEAR_COLUMN )
{
String column_name = command . column_name . safeGet < String > ( ) ;
2018-05-15 12:56:14 +00:00
if ( ! table . getColumns ( ) . hasPhysical ( column_name ) )
2017-07-14 18:09:28 +00:00
{
throw Exception ( " Wrong column name. Cannot find column " + column_name + " to clear it from partition " ,
DB : : ErrorCodes : : ILLEGAL_COLUMN ) ;
}
}
}
}
2016-01-11 21:46:36 +00:00
}