| 158 | } |
| 159 | |
| 160 | BlockIO InterpreterDropQuery::executeToTableImpl(ASTDropQuery & query, DatabasePtr & db, UUID & uuid_to_wait) |
| 161 | { |
| 162 | /// NOTE: it does not contain UUID, we will resolve it with locked DDLGuard |
| 163 | auto table_id = StorageID(query); |
| 164 | if (query.temporary || table_id.database_name.empty()) |
| 165 | { |
| 166 | if (getContext()->tryResolveStorageID(table_id, Context::ResolveExternal)) |
| 167 | return executeToTemporaryTable(table_id.getTableName(), query.kind); |
| 168 | else |
| 169 | query.database = table_id.database_name = getContext()->getCurrentDatabase(); |
| 170 | } |
| 171 | |
| 172 | if (query.temporary) |
| 173 | { |
| 174 | if (query.if_exists) |
| 175 | return {}; |
| 176 | throw Exception("Temporary table " + backQuoteIfNeed(table_id.table_name) + " doesn't exist", |
| 177 | ErrorCodes::UNKNOWN_TABLE); |
| 178 | } |
| 179 | |
| 180 | auto ddl_guard = (!query.no_ddl_lock ? DatabaseCatalog::instance().getDDLGuard(table_id.database_name, table_id.table_name) : nullptr); |
| 181 | |
| 182 | /// If table was already dropped by anyone, an exception will be thrown |
| 183 | auto [database, table] = query.if_exists ? DatabaseCatalog::instance().tryGetDatabaseAndTable(table_id, getContext()) |
| 184 | : DatabaseCatalog::instance().getDatabaseAndTable(table_id, getContext()); |
| 185 | |
| 186 | if (database && table) |
| 187 | { |
| 188 | IntentLockPtr table_lock; |
| 189 | if (database->getEngineName().starts_with("Cnch")) |
| 190 | { |
| 191 | auto txn = getContext()->getCurrentTransaction(); |
| 192 | if (!txn) |
| 193 | throw Exception("Transaction not initialized", ErrorCodes::CNCH_TRANSACTION_NOT_INITIALIZED); |
| 194 | table_lock = txn->createIntentLock(IntentLock::TB_LOCK_PREFIX, database->getDatabaseName(), table->getTableName()); |
| 195 | table_lock->lock(); |
| 196 | } |
| 197 | auto & ast_drop_query = query.as<ASTDropQuery &>(); |
| 198 | |
| 199 | if (ast_drop_query.is_view && !table->isView()) |
| 200 | throw Exception(ErrorCodes::INCORRECT_QUERY, |
| 201 | "Table {} is not a View", |
| 202 | table_id.getNameForLogs()); |
| 203 | |
| 204 | if (ast_drop_query.is_dictionary && !table->isDictionary()) |
| 205 | throw Exception(ErrorCodes::INCORRECT_QUERY, |
| 206 | "Table {} is not a Dictionary", |
| 207 | table_id.getNameForLogs()); |
| 208 | |
| 209 | /// Now get UUID, so we can wait for table data to be finally dropped |
| 210 | table_id.uuid = database->tryGetTableUUID(table_id.table_name); |
| 211 | |
| 212 | /// Prevents recursive drop from drop database query. The original query must specify a table. |
| 213 | bool is_drop_or_detach_database = query_ptr->as<ASTDropQuery>()->table.empty(); |
| 214 | bool is_replicated_ddl_query = typeid_cast<DatabaseReplicated *>(database.get()) && |
| 215 | !getContext()->getClientInfo().is_replicated_database_internal && |
| 216 | !is_drop_or_detach_database; |
| 217 |
nothing calls this directly
no test coverage detected