diff --git a/src/Analyzer/Resolve/IdentifierResolver.cpp b/src/Analyzer/Resolve/IdentifierResolver.cpp index 083b3a8f462..7d5beae6e51 100644 --- a/src/Analyzer/Resolve/IdentifierResolver.cpp +++ b/src/Analyzer/Resolve/IdentifierResolver.cpp @@ -412,27 +412,41 @@ QueryTreeNodePtr IdentifierResolver::tryResolveTableIdentifierFromDatabaseCatalo table_name = table_identifier[0]; } - StorageID storage_id(database_name, table_name); - storage_id = context->resolveStorageID(storage_id); - bool is_temporary_table = storage_id.getDatabaseName() == DatabaseCatalog::TEMPORARY_DATABASE; + const int max_retry = 5; + for (int i = 0; i < max_retry; ++i) + { + StorageID storage_id(database_name, table_name); + storage_id = context->resolveStorageID(storage_id); + bool is_temporary_table = storage_id.getDatabaseName() == DatabaseCatalog::TEMPORARY_DATABASE; - StoragePtr storage; + StoragePtr storage; - if (is_temporary_table) - storage = DatabaseCatalog::instance().getTable(storage_id, context); - else - storage = DatabaseCatalog::instance().tryGetTable(storage_id, context); + if (is_temporary_table) + storage = DatabaseCatalog::instance().getTable(storage_id, context); + else + storage = DatabaseCatalog::instance().tryGetTable(storage_id, context); - if (!storage) - return {}; + if (!storage) + return {}; - auto storage_lock = storage->lockForShare(context->getInitialQueryId(), context->getSettingsRef()[Setting::lock_acquire_timeout]); - auto storage_snapshot = storage->getStorageSnapshot(storage->getInMemoryMetadataPtr(), context); - auto result = std::make_shared(std::move(storage), std::move(storage_lock), std::move(storage_snapshot)); - if (is_temporary_table) - result->setTemporaryTableName(table_name); + auto storage_lock + = storage->tryLockForShare(context->getInitialQueryId(), context->getSettingsRef()[Setting::lock_acquire_timeout]); + /// If storage is dropped or detached, it is unable to get the lock. We retry with the new table if exists. + if (!storage_lock) + continue; - return result; + auto storage_snapshot = storage->getStorageSnapshot(storage->getInMemoryMetadataPtr(), context); + auto result = std::make_shared(std::move(storage), std::move(storage_lock), std::move(storage_snapshot)); + if (is_temporary_table) + result->setTemporaryTableName(table_name); + + return result; + } + + throw Exception( + ErrorCodes::INVALID_IDENTIFIER, + "Unable to resolve table identifier: {}, the table is dropped or detached", + table_identifier.getFullName()); } /// Resolve identifier from compound expression diff --git a/tests/queries/0_stateless/03237_create-or-replace-view-atomically-with-atomic-engine.sh b/tests/queries/0_stateless/03237_create-or-replace-view-atomically-with-atomic-engine.sh deleted file mode 100755 index b8745f149de..00000000000 --- a/tests/queries/0_stateless/03237_create-or-replace-view-atomically-with-atomic-engine.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/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..50}; do - $CLICKHOUSE_CLIENT --query "CREATE OR REPLACE VIEW ${CLICKHOUSE_DATABASE}_db.test_view AS SELECT 'abcdef'" - done -} -export -f create_or_replace_view_thread; - -function select_view_thread -{ - for _ in {1..50}; do - $CLICKHOUSE_CLIENT --query "SELECT * FROM ${CLICKHOUSE_DATABASE}_db.test_view" | grep -v "abcdef" - done -} -export -f select_view_thread; - -$CLICKHOUSE_CLIENT --query "CREATE OR REPLACE VIEW ${CLICKHOUSE_DATABASE}_db.test_view AS SELECT 'abcdef'" - -bash -c create_or_replace_view_thread & -bash -c create_or_replace_view_thread & -bash -c create_or_replace_view_thread & -bash -c create_or_replace_view_thread & -bash -c create_or_replace_view_thread & -bash -c create_or_replace_view_thread & -bash -c create_or_replace_view_thread & -bash -c create_or_replace_view_thread & - -bash -c select_view_thread & -bash -c select_view_thread & -bash -c select_view_thread & -bash -c select_view_thread & -bash -c select_view_thread & -bash -c select_view_thread & -bash -c select_view_thread & -bash -c select_view_thread & - -wait \ No newline at end of file diff --git a/tests/queries/0_stateless/03237_create-or-replace-view-atomically-with-atomic-engine.reference b/tests/queries/0_stateless/03237_create_or_replace_view_atomically_with_atomic_engine.reference similarity index 100% rename from tests/queries/0_stateless/03237_create-or-replace-view-atomically-with-atomic-engine.reference rename to tests/queries/0_stateless/03237_create_or_replace_view_atomically_with_atomic_engine.reference diff --git a/tests/queries/0_stateless/03237_create_or_replace_view_atomically_with_atomic_engine.sh b/tests/queries/0_stateless/03237_create_or_replace_view_atomically_with_atomic_engine.sh new file mode 100755 index 00000000000..54d58e0cf8f --- /dev/null +++ b/tests/queries/0_stateless/03237_create_or_replace_view_atomically_with_atomic_engine.sh @@ -0,0 +1,58 @@ +#!/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..10}; do + $CLICKHOUSE_CLIENT --query "CREATE OR REPLACE VIEW ${CLICKHOUSE_DATABASE}_db.test_view AS SELECT 'abcdef'" > /dev/null + done +} +export -f create_or_replace_view_thread; + +function select_view_thread +{ + for _ in {1..10}; do + $CLICKHOUSE_CLIENT --query "SELECT * FROM ${CLICKHOUSE_DATABASE}_db.test_view" > /dev/null + done +} +export -f select_view_thread; + +$CLICKHOUSE_CLIENT --query "CREATE OR REPLACE VIEW ${CLICKHOUSE_DATABASE}_db.test_view AS SELECT 'abcdef'" > /dev/null +{ + bash -c select_view_thread & + bash -c select_view_thread & + bash -c select_view_thread & + bash -c select_view_thread & + bash -c select_view_thread & + bash -c select_view_thread & + bash -c select_view_thread & + bash -c select_view_thread & + bash -c select_view_thread & + bash -c select_view_thread & + bash -c select_view_thread & + bash -c select_view_thread & + + bash -c create_or_replace_view_thread & + bash -c create_or_replace_view_thread & + bash -c create_or_replace_view_thread & + bash -c create_or_replace_view_thread & + bash -c create_or_replace_view_thread & + bash -c create_or_replace_view_thread & + bash -c create_or_replace_view_thread & + bash -c create_or_replace_view_thread & + bash -c create_or_replace_view_thread & + bash -c create_or_replace_view_thread & +} > >(cat) 2> >(cat >&2) + +for _ in {1..100}; do + $CLICKHOUSE_CLIENT --query "SELECT * FROM ${CLICKHOUSE_DATABASE}_db.test_view" | grep -v abcdef +done + +wait \ No newline at end of file diff --git a/tests/queries/0_stateless/03238_create-or-replace-view-atomically-with-replicated-engine.reference b/tests/queries/0_stateless/03238_create_or_replace_view_atomically_with_replicated_engine.reference similarity index 100% rename from tests/queries/0_stateless/03238_create-or-replace-view-atomically-with-replicated-engine.reference rename to tests/queries/0_stateless/03238_create_or_replace_view_atomically_with_replicated_engine.reference diff --git a/tests/queries/0_stateless/03238_create-or-replace-view-atomically-with-replicated-engine.sh b/tests/queries/0_stateless/03238_create_or_replace_view_atomically_with_replicated_engine.sh similarity index 86% rename from tests/queries/0_stateless/03238_create-or-replace-view-atomically-with-replicated-engine.sh rename to tests/queries/0_stateless/03238_create_or_replace_view_atomically_with_replicated_engine.sh index 151dea8db0d..dd994eb23fd 100755 --- a/tests/queries/0_stateless/03238_create-or-replace-view-atomically-with-replicated-engine.sh +++ b/tests/queries/0_stateless/03238_create_or_replace_view_atomically_with_replicated_engine.sh @@ -10,21 +10,21 @@ $CLICKHOUSE_CLIENT --query "CREATE DATABASE ${CLICKHOUSE_DATABASE}_db ENGINE=Rep function create_or_replace_view_thread { - for _ in {1..50}; do - $CLICKHOUSE_CLIENT --query "CREATE OR REPLACE VIEW ${CLICKHOUSE_DATABASE}_db.test_view AS SELECT 'abcdef'" + for _ in {1..10}; do + $CLICKHOUSE_CLIENT --query "CREATE OR REPLACE VIEW ${CLICKHOUSE_DATABASE}_db.test_view AS SELECT 'abcdef'" > /dev/null done } export -f create_or_replace_view_thread; function select_view_thread { - for _ in {1..50}; do - $CLICKHOUSE_CLIENT --query "SELECT * FROM ${CLICKHOUSE_DATABASE}_db.test_view" | grep -v "abcdef" + for _ in {1..10}; do + $CLICKHOUSE_CLIENT --query "SELECT * FROM ${CLICKHOUSE_DATABASE}_db.test_view" > /dev/null done } export -f select_view_thread; -$CLICKHOUSE_CLIENT --query "CREATE OR REPLACE VIEW ${CLICKHOUSE_DATABASE}_db.test_view AS SELECT 'abcdef'" +$CLICKHOUSE_CLIENT --query "CREATE OR REPLACE VIEW ${CLICKHOUSE_DATABASE}_db.test_view AS SELECT 'abcdef'" > /dev/null bash -c create_or_replace_view_thread & bash -c create_or_replace_view_thread &