Make CREATE OR REPLACE VIEW an atomic operation in Atomic & Replicated DB engines

This commit is contained in:
Tuan Pham Anh 2024-09-20 10:00:02 +00:00
parent 9e12b6cb4e
commit 48bbb844c2
3 changed files with 48 additions and 4 deletions

View File

@ -1588,7 +1588,8 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create)
if (need_add_to_database && !database)
throw Exception(ErrorCodes::UNKNOWN_DATABASE, "Database {} does not exist", backQuoteIfNeed(database_name));
if (create.replace_table)
if (create.replace_table
|| (create.replace_view && (database->getEngineName() == "Atomic" || database->getEngineName() == "Replicated")))
{
chassert(!ddl_guard);
return doCreateOrReplaceTable(create, properties, mode);
@ -1941,16 +1942,16 @@ BlockIO InterpreterCreateQuery::doCreateOrReplaceTable(ASTCreateQuery & create,
auto ast_rename = std::make_shared<ASTRenameQuery>(ASTRenameQuery::Elements{std::move(elem)});
ast_rename->dictionary = create.is_dictionary;
if (create.create_or_replace)
if (create.create_or_replace || create.replace_view)
{
/// CREATE OR REPLACE TABLE
/// CREATE OR REPLACE TABLE/VIEW
/// Will execute ordinary RENAME instead of EXCHANGE if the target table does not exist
ast_rename->rename_if_cannot_exchange = true;
ast_rename->exchange = false;
}
else
{
/// REPLACE TABLE
/// REPLACE TABLE/VIEW
/// Will execute EXCHANGE query and fail if the target table does not exist
ast_rename->exchange = true;
}

View File

@ -0,0 +1,43 @@
#!/usr/bin/env bash
CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=../shell_config.sh
. "$CUR_DIR"/../shell_config.sh
# with Atomic engine
$CLICKHOUSE_CLIENT --query "DROP DATABASE IF EXISTS ${CLICKHOUSE_DATABASE}_db"
$CLICKHOUSE_CLIENT --query "CREATE DATABASE ${CLICKHOUSE_DATABASE}_db ENGINE=Atomic"
function create_or_replace_view_thread
{
for _ in {1..1000}; do
$CLICKHOUSE_CLIENT --query "CREATE OR REPLACE VIEW ${CLICKHOUSE_DATABASE}_db.test_view AS SELECT 1"
done
}
export -f create_or_replace_view_thread;
bash -c create_or_replace_view_thread 2> /dev/null &
$CLICKHOUSE_CLIENT --query "CREATE OR REPLACE VIEW ${CLICKHOUSE_DATABASE}_db.test_view AS SELECT 1"
for _ in {1..1000}; do
$CLICKHOUSE_CLIENT --query "SELECT * FROM ${CLICKHOUSE_DATABASE}_db.test_view" > /dev/null
done
wait
# with Replicated engine
$CLICKHOUSE_CLIENT --query "DROP DATABASE IF EXISTS ${CLICKHOUSE_DATABASE}_db"
$CLICKHOUSE_CLIENT --query "CREATE DATABASE ${CLICKHOUSE_DATABASE}_db ENGINE=Replicated"
TIMEOUT=20
timeout $TIMEOUT bash -c create_or_replace_view_thread 2> /dev/null &
$CLICKHOUSE_CLIENT --query "CREATE OR REPLACE VIEW ${CLICKHOUSE_DATABASE}_db.test_view AS SELECT 1"
for _ in {1..1000}; do
$CLICKHOUSE_CLIENT --query "SELECT * FROM ${CLICKHOUSE_DATABASE}_db.test_view" > /dev/null
done
wait