| 2312 | } |
| 2313 | |
| 2314 | void DatabaseReplicated::commitCreateTable(const ASTCreateQuery & query, const StoragePtr & table, |
| 2315 | const String & table_metadata_tmp_path, const String & table_metadata_path, |
| 2316 | ContextPtr query_context) |
| 2317 | { |
| 2318 | auto txn = query_context->getZooKeeperMetadataTransaction(); |
| 2319 | chassert(!ddl_worker->isCurrentlyActive() || txn); |
| 2320 | |
| 2321 | String statement = getObjectDefinitionFromCreateQuery(query.clone()); |
| 2322 | |
| 2323 | /// For CREATE OR REPLACE, the metadata node for the temporary table is intentionally omitted |
| 2324 | /// from the transaction because renameTable will create it under the final name atomically. |
| 2325 | /// However, inner tables (`.inner_id.*`) are NOT renamed during the exchange — they keep |
| 2326 | /// their UUID-based name — so their metadata nodes must still be created here, as part of |
| 2327 | /// the rename transaction that commits everything. Without this, an explicit DROP TABLE |
| 2328 | /// after CREATE OR REPLACE would fail with a ZooKeeper "No node" error when trying to |
| 2329 | /// remove the inner table's metadata node. |
| 2330 | const bool is_inner_table = query.getTable().starts_with(".inner_id."); |
| 2331 | if (txn && txn->isInitialQuery() && (!txn->isCreateOrReplaceQuery() || is_inner_table)) |
| 2332 | { |
| 2333 | String metadata_zk_path = zookeeper_path + "/metadata/" + escapeForFileName(query.getTable()); |
| 2334 | /// zk::multi(...) will throw if `metadata_zk_path` exists |
| 2335 | txn->addOp(zkutil::makeCreateRequest(metadata_zk_path, statement, zkutil::CreateMode::Persistent)); |
| 2336 | } |
| 2337 | |
| 2338 | std::lock_guard lock{metadata_mutex}; |
| 2339 | UInt64 new_digest = tables_metadata_digest; |
| 2340 | new_digest += DB::getMetadataHash(query.getTable(), statement); |
| 2341 | if (txn && !txn->isCreateOrReplaceQuery() && !is_recovering) |
| 2342 | txn->addOp(zkutil::makeSetRequest(replica_path + "/digest", toString(new_digest), -1)); |
| 2343 | |
| 2344 | DatabaseAtomic::commitCreateTable(query, table, table_metadata_tmp_path, table_metadata_path, query_context); |
| 2345 | tables_metadata_digest = new_digest; |
| 2346 | |
| 2347 | /// commitCreateTable() commits the txn, so no need to try to attach it to txn |
| 2348 | assertDigest(query_context); |
| 2349 | } |
| 2350 | |
| 2351 | void DatabaseReplicated::commitAlterTable(const StorageID & table_id, |
| 2352 | const String & table_metadata_tmp_path, const String & table_metadata_path, |
nothing calls this directly
no test coverage detected