Throw an error if CLONE ASfrom a Replicated storage

This commit is contained in:
Tuan Pham Anh 2024-09-06 06:32:16 +00:00
parent d0c6d8f118
commit 5b4a9bc62b
3 changed files with 56 additions and 31 deletions

View File

@ -1468,44 +1468,53 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create)
if (create.select && create.is_materialized_view && mode <= LoadingStrictnessLevel::CREATE)
validateMaterializedViewColumnsAndEngine(create, properties, database);
bool allow_heavy_populate = getContext()->getSettingsRef().database_replicated_allow_heavy_create && create.is_populate;
if (!allow_heavy_populate && database && database->getEngineName() == "Replicated" && (create.select || create.is_populate))
bool is_storage_replicated = false;
if (create.storage && isReplicated(*create.storage))
is_storage_replicated = true;
if (create.targets)
{
bool is_storage_replicated = false;
if (create.storage && isReplicated(*create.storage))
is_storage_replicated = true;
if (create.targets)
for (const auto & inner_table_engine : create.targets->getInnerEngines())
{
for (const auto & inner_table_engine : create.targets->getInnerEngines())
if (isReplicated(*inner_table_engine))
is_storage_replicated = true;
}
}
bool allow_heavy_populate = getContext()->getSettingsRef().database_replicated_allow_heavy_create && create.is_populate;
if (!allow_heavy_populate && database && database->getEngineName() == "Replicated" && (create.select || create.is_populate))
{
const bool allow_create_select_for_replicated
= (create.isView() && !create.is_populate) || create.is_create_empty || !is_storage_replicated;
if (!allow_create_select_for_replicated)
{
if (isReplicated(*inner_table_engine))
is_storage_replicated = true;
/// POPULATE can be enabled with setting, provide hint in error message
if (create.is_populate)
throw Exception(
ErrorCodes::SUPPORT_IS_DISABLED,
"CREATE with POPULATE is not supported with Replicated databases. Consider using separate CREATE and INSERT "
"queries. "
"Alternatively, you can enable 'database_replicated_allow_heavy_create' setting to allow this operation, use with "
"caution");
throw Exception(
ErrorCodes::SUPPORT_IS_DISABLED,
"CREATE AS SELECT is not supported with Replicated databases. Consider using separate CREATE and INSERT queries.");
}
}
const bool allow_create_select_for_replicated = (create.isView() && !create.is_populate) || create.is_create_empty || !is_storage_replicated;
if (!allow_create_select_for_replicated)
{
/// POPULATE can be enabled with setting, provide hint in error message
if (create.is_populate)
throw Exception(
ErrorCodes::SUPPORT_IS_DISABLED,
"CREATE with POPULATE is not supported with Replicated databases. Consider using separate CREATE and INSERT queries. "
"Alternatively, you can enable 'database_replicated_allow_heavy_create' setting to allow this operation, use with caution");
if (create.is_clone_as)
{
if (database && database->getEngineName() == "Replicated")
throw Exception(
ErrorCodes::SUPPORT_IS_DISABLED,
"CREATE AS SELECT is not supported with Replicated databases. Consider using separate CREATE and INSERT queries.");
}
}
"CREATE CLONE AS is not supported with Replicated databases. Consider using separate CREATE and INSERT queries.");
if (database && database->getEngineName() == "Replicated" && create.is_clone_as)
{
throw Exception(
ErrorCodes::SUPPORT_IS_DISABLED,
"CREATE CLONE AS is not supported with Replicated databases. Consider using separate CREATE and INSERT queries.");
if (is_storage_replicated)
throw Exception(
ErrorCodes::SUPPORT_IS_DISABLED,
"CREATE CLONE AS is not supported with Replicated storages. Consider using separate CREATE and INSERT queries.");
}
if (database && database->shouldReplicateQuery(getContext(), query_ptr))

View File

@ -22,6 +22,10 @@ from foo_replacing_merge_tree
from clone_as_foo_replacing_merge_tree
1 a
2 b
CREATE TABLE default.foo_replicated_merge_tree\n(\n `x` Int8,\n `y` String\n)\nENGINE = ReplicatedMergeTree(\'/clickhouse/tables/default/test_foo_replicated_merge_tree\', \'r1\')\nPRIMARY KEY x\nORDER BY x\nSETTINGS index_granularity = 8192
1 a
2 b
1
s1 r1 OK 0 0
CREATE TABLE imdb_03231.foo_merge_tree\n(\n `x` Int8,\n `y` String\n)\nENGINE = MergeTree\nPRIMARY KEY x\nORDER BY x\nSETTINGS index_granularity = 8192
from imdb_03231.foo_merge_tree

View File

@ -13,6 +13,8 @@ ${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS foo_merge_tree"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS clone_as_foo_merge_tree"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS foo_replacing_merge_tree"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS clone_as_foo_replacing_merge_tree"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS foo_replicated_merge_tree"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS clone_as_foo_replicated_merge_tree"
# CLONE AS with a table of Memory engine
${CLICKHOUSE_CLIENT} --optimize_throw_if_noop 1 -q "CREATE TABLE foo_memory (x Int8, y String) ENGINE=Memory"
@ -55,7 +57,15 @@ ${CLICKHOUSE_CLIENT} --optimize_throw_if_noop 1 -q "SHOW CREATE TABLE clone_as_f
echo "from foo_replacing_merge_tree"
${CLICKHOUSE_CLIENT} --optimize_throw_if_noop 1 -q "SELECT * FROM foo_replacing_merge_tree"
echo "from clone_as_foo_replacing_merge_tree"
${CLICKHOUSE_CLIENT} --optimize_throw_if_noop 1 -q "SELECT * FROM clone_as_foo_replacing_merge_tree FINAL"
${CLICKHOUSE_CLIENT} --optimize_throw_if_noop 1 -q "SELECT * FROM clone_as_foo_replacing_merge_tree"
# CLONE AS with a table of ReplicatedMergeTree engine
${CLICKHOUSE_CLIENT} --optimize_throw_if_noop 1 -q "CREATE TABLE foo_replicated_merge_tree (x Int8, y String) ENGINE=ReplicatedMergeTree('/clickhouse/tables/$CLICKHOUSE_DATABASE/test_foo_replicated_merge_tree', 'r1') PRIMARY KEY x"
${CLICKHOUSE_CLIENT} --optimize_throw_if_noop 1 -q "SHOW CREATE TABLE foo_replicated_merge_tree"
${CLICKHOUSE_CLIENT} --optimize_throw_if_noop 1 -q "INSERT INTO foo_replicated_merge_tree VALUES (1, 'a'), (2, 'b')"
${CLICKHOUSE_CLIENT} --optimize_throw_if_noop 1 -q "SELECT * FROM foo_replicated_merge_tree"
echo "$(${CLICKHOUSE_CLIENT} --optimize_throw_if_noop 1 --server_logs_file=/dev/null -q "CREATE TABLE clone_as_foo_replicated_merge_tree CLONE AS foo_replicated_merge_tree" 2>&1)" \
| grep -c 'Code: 344. DB::Exception: .* CREATE CLONE AS is not supported with Replicated storages. Consider using separate CREATE and INSERT queries.'
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS foo_memory"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS clone_as_foo_memory"
@ -65,11 +75,13 @@ ${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS foo_merge_tree"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS clone_as_foo_merge_tree"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS foo_replacing_merge_tree"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS clone_as_foo_replacing_merge_tree"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS foo_replicated_merge_tree"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS clone_as_foo_replicated_merge_tree"
# CLONE AS with a Replicated database
${CLICKHOUSE_CLIENT} -q "DROP DATABASE IF EXISTS imdb_03231"
${CLICKHOUSE_CLIENT} -q "CREATE DATABASE imdb_03231 ENGINE = Replicated('/test/databases/imdb_03231', 's1', 'r1')"
${CLICKHOUSE_CLIENT} -q "CREATE DATABASE imdb_03231 ENGINE = Replicated('/test/databases/$CLICKHOUSE_DATABASE/imdb_03231', 's1', 'r1')"
${CLICKHOUSE_CLIENT} --optimize_throw_if_noop 1 -q "CREATE TABLE imdb_03231.foo_merge_tree (x Int8, y String) ENGINE=MergeTree PRIMARY KEY x"
${CLICKHOUSE_CLIENT} --optimize_throw_if_noop 1 -q "SHOW CREATE TABLE imdb_03231.foo_merge_tree"