2022-06-07 05:20:46 +00:00
# include <Interpreters/InterpreterDeleteQuery.h>
# include <Access/ContextAccess.h>
# include <Databases/DatabaseReplicated.h>
# include <Databases/IDatabase.h>
# include <Interpreters/Context.h>
# include <Interpreters/FunctionNameNormalizer.h>
# include <Interpreters/MutationsInterpreter.h>
# include <Parsers/ASTDeleteQuery.h>
2022-07-12 20:56:15 +00:00
# include <Parsers/ASTAssignment.h>
# include <Parsers/ASTExpressionList.h>
2022-06-07 05:20:46 +00:00
# include <Storages/AlterCommands.h>
# include <Storages/IStorage.h>
# include <Storages/MutationCommands.h>
2022-07-21 19:50:19 +00:00
# include <Storages/LightweightDeleteDescription.h>
2022-08-08 17:04:35 +00:00
# include <Storages/MergeTree/MergeTreeData.h>
2022-06-07 05:20:46 +00:00
namespace DB
{
namespace ErrorCodes
{
extern const int TABLE_IS_READ_ONLY ;
2022-07-06 10:29:29 +00:00
extern const int SUPPORT_IS_DISABLED ;
2022-12-29 11:24:48 +00:00
extern const int BAD_ARGUMENTS ;
2022-06-07 05:20:46 +00:00
}
InterpreterDeleteQuery : : InterpreterDeleteQuery ( const ASTPtr & query_ptr_ , ContextPtr context_ ) : WithContext ( context_ ) , query_ptr ( query_ptr_ )
{
}
BlockIO InterpreterDeleteQuery : : execute ( )
{
FunctionNameNormalizer ( ) . visit ( query_ptr . get ( ) ) ;
const ASTDeleteQuery & delete_query = query_ptr - > as < ASTDeleteQuery & > ( ) ;
auto table_id = getContext ( ) - > resolveStorageID ( delete_query , Context : : ResolveOrdinary ) ;
getContext ( ) - > checkAccess ( AccessType : : ALTER_DELETE , table_id ) ;
query_ptr - > as < ASTDeleteQuery & > ( ) . setDatabase ( table_id . database_name ) ;
/// First check table storage for validations.
StoragePtr table = DatabaseCatalog : : instance ( ) . getTable ( table_id , getContext ( ) ) ;
checkStorageSupportsTransactionsIfNeeded ( table , getContext ( ) ) ;
if ( table - > isStaticStorage ( ) )
throw Exception ( ErrorCodes : : TABLE_IS_READ_ONLY , " Table is read-only " ) ;
DatabasePtr database = DatabaseCatalog : : instance ( ) . getDatabase ( table_id . database_name ) ;
2022-09-15 19:15:57 +00:00
if ( database - > shouldReplicateQuery ( getContext ( ) , query_ptr ) )
2022-06-07 05:20:46 +00:00
{
auto guard = DatabaseCatalog : : instance ( ) . getDDLGuard ( table_id . database_name , table_id . table_name ) ;
guard - > releaseTableLock ( ) ;
2022-09-16 14:25:32 +00:00
return database - > tryEnqueueReplicatedDDL ( query_ptr , getContext ( ) ) ;
2022-06-07 05:20:46 +00:00
}
auto table_lock = table - > lockForShare ( getContext ( ) - > getCurrentQueryId ( ) , getContext ( ) - > getSettingsRef ( ) . lock_acquire_timeout ) ;
auto metadata_snapshot = table - > getInMemoryMetadataPtr ( ) ;
2022-12-29 11:24:48 +00:00
if ( table - > supportsDelete ( ) )
2022-08-31 13:08:27 +00:00
{
/// Convert to MutationCommand
MutationCommands mutation_commands ;
MutationCommand mut_command ;
mut_command . type = MutationCommand : : Type : : DELETE ;
mut_command . predicate = delete_query . predicate ;
mutation_commands . emplace_back ( mut_command ) ;
table - > checkMutationIsPossible ( mutation_commands , getContext ( ) - > getSettingsRef ( ) ) ;
MutationsInterpreter ( table , metadata_snapshot , mutation_commands , getContext ( ) , false ) . validate ( ) ;
2022-12-29 17:25:18 +00:00
table - > mutate ( mutation_commands , getContext ( ) , false ) ;
2022-08-31 13:08:27 +00:00
return { } ;
}
2022-12-29 11:24:48 +00:00
else if ( table - > supportsLightweightDelete ( ) )
{
if ( ! getContext ( ) - > getSettingsRef ( ) . allow_experimental_lightweight_delete )
throw Exception ( ErrorCodes : : SUPPORT_IS_DISABLED , " Lightweight delete mutate is experimental. Set `allow_experimental_lightweight_delete` setting to enable it " ) ;
/// Convert to MutationCommand
MutationCommands mutation_commands ;
MutationCommand mut_command ;
/// Build "UPDATE _row_exists = 0 WHERE predicate" query
mut_command . type = MutationCommand : : Type : : UPDATE ;
mut_command . predicate = delete_query . predicate ;
auto command = std : : make_shared < ASTAlterCommand > ( ) ;
command - > type = ASTAlterCommand : : UPDATE ;
command - > predicate = delete_query . predicate ;
command - > update_assignments = std : : make_shared < ASTExpressionList > ( ) ;
auto set_row_does_not_exist = std : : make_shared < ASTAssignment > ( ) ;
set_row_does_not_exist - > column_name = LightweightDeleteDescription : : FILTER_COLUMN . name ;
auto zero_value = std : : make_shared < ASTLiteral > ( DB : : Field ( UInt8 ( 0 ) ) ) ;
set_row_does_not_exist - > children . push_back ( zero_value ) ;
command - > update_assignments - > children . push_back ( set_row_does_not_exist ) ;
command - > children . push_back ( command - > predicate ) ;
command - > children . push_back ( command - > update_assignments ) ;
mut_command . column_to_update_expression [ set_row_does_not_exist - > column_name ] = zero_value ;
mut_command . ast = command - > ptr ( ) ;
mutation_commands . emplace_back ( mut_command ) ;
table - > checkMutationIsPossible ( mutation_commands , getContext ( ) - > getSettingsRef ( ) ) ;
MutationsInterpreter ( table , metadata_snapshot , mutation_commands , getContext ( ) , false ) . validate ( ) ;
2022-12-29 17:25:18 +00:00
table - > mutate ( mutation_commands , getContext ( ) , true ) ;
2022-08-31 13:08:27 +00:00
2022-12-29 11:24:48 +00:00
return { } ;
}
else
{
2022-12-31 00:40:50 +00:00
throw Exception ( ErrorCodes : : BAD_ARGUMENTS , " DELETE query is not supported for table {} " , table - > getStorageID ( ) . getFullTableName ( ) ) ;
2022-12-29 11:24:48 +00:00
}
2022-06-07 05:20:46 +00:00
}
}