Disable ATTACH/DETACH TABLE <DICTIONARY>

This commit is contained in:
Amos Bird 2020-11-11 22:34:58 +08:00
parent 4eb684603a
commit 134786afd5
No known key found for this signature in database
GPG Key ID: 80D430DCBECFEDB4
7 changed files with 39 additions and 0 deletions

View File

@ -684,6 +684,10 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create)
// Table SQL definition is available even if the table is detached
auto query = database->getCreateTableQuery(create.table, context);
create = query->as<ASTCreateQuery &>(); // Copy the saved create query, but use ATTACH instead of CREATE
if (create.is_dictionary)
throw Exception(
"Cannot ATTACH TABLE " + backQuoteIfNeed(database_name) + "." + backQuoteIfNeed(create.table) + ", it is a Dictionary",
ErrorCodes::INCORRECT_QUERY);
create.attach = true;
create.attach_short_syntax = true;
create.if_not_exists = if_not_exists;

View File

@ -119,6 +119,7 @@ BlockIO InterpreterDropQuery::executeToTableImpl(const ASTDropQuery & query, Dat
if (query.kind == ASTDropQuery::Kind::Detach)
{
context.checkAccess(table->isView() ? AccessType::DROP_VIEW : AccessType::DROP_TABLE, table_id);
table->checkTableCanBeDetached();
table->shutdown();
TableExclusiveLockHolder table_lock;
if (database->getEngineName() != "Atomic")

View File

@ -443,6 +443,8 @@ public:
/// Otherwise - throws an exception with detailed information.
/// We do not use mutex because it is not very important that the size could change during the operation.
virtual void checkTableCanBeDropped() const {}
/// Similar to above but checks for DETACH. It's only used for DICTIONARIES.
virtual void checkTableCanBeDetached() const {}
/// Checks that Partition could be dropped right now
/// Otherwise - throws an exception with detailed information.

View File

@ -130,6 +130,11 @@ void StorageDictionary::checkTableCanBeDropped() const
throw Exception("Cannot detach table " + getStorageID().getFullTableName() + " from a database with DICTIONARY engine", ErrorCodes::CANNOT_DETACH_DICTIONARY_AS_TABLE);
}
void StorageDictionary::checkTableCanBeDetached() const
{
checkTableCanBeDropped();
}
Pipe StorageDictionary::read(
const Names & column_names,
const StorageMetadataPtr & /*metadata_snapshot*/,

View File

@ -15,6 +15,7 @@ public:
std::string getName() const override { return "Dictionary"; }
void checkTableCanBeDropped() const override;
void checkTableCanBeDetached() const override;
Pipe read(
const Names & column_names,

View File

@ -0,0 +1,26 @@
DROP DATABASE IF EXISTS database_for_dict;
CREATE DATABASE database_for_dict;
CREATE TABLE database_for_dict.table_for_dict (k UInt64, v UInt8) ENGINE = MergeTree ORDER BY k;
DROP DICTIONARY IF EXISTS database_for_dict.dict1;
CREATE DICTIONARY database_for_dict.dict1 (k UInt64 DEFAULT 0, v UInt8 DEFAULT 1) PRIMARY KEY k
SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'table_for_dict' PASSWORD '' DB 'database_for_dict'))
LIFETIME(MIN 1 MAX 10)
LAYOUT(FLAT());
DETACH TABLE database_for_dict.dict1; -- { serverError 520 }
DETACH DICTIONARY database_for_dict.dict1;
ATTACH TABLE database_for_dict.dict1; -- { serverError 80 }
ATTACH DICTIONARY database_for_dict.dict1;
DROP DICTIONARY database_for_dict.dict1;
DROP TABLE database_for_dict.table_for_dict;
DROP DATABASE IF EXISTS database_for_dict;