void ASTInsertQuery::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const { frame.need_parens = false; settings.ostr << (settings.hilite ? hilite_keyword : "") << "INSERT INTO " << (settings.hilite ? hilite_none : "") << (!database.empty() ? backQuoteIfNeed(database) + "." : "") << backQuoteIfNeed(table); if (columns) { settings.ostr << " ("; columns->formatImpl(settings, state, frame); settings.ostr << ")"; } if (select) { settings.ostr << " "; select->formatImpl(settings, state, frame); } else { if (!format.empty()) { settings.ostr << (settings.hilite ? hilite_keyword : "") << " FORMAT " << (settings.hilite ? hilite_none : "") << format; } else { settings.ostr << (settings.hilite ? hilite_keyword : "") << " VALUES" << (settings.hilite ? hilite_none : ""); } } }
ASTPtr DatabaseDictionary::getCreateTableQueryImpl(const Context & context, const String & table_name, bool throw_on_error) const { String query; { WriteBufferFromString buffer(query); const auto & dictionaries = context.getExternalDictionaries(); auto dictionary = throw_on_error ? dictionaries.getDictionary(table_name) : dictionaries.tryGetDictionary(table_name); auto names_and_types = StorageDictionary::getNamesAndTypes(dictionary->getStructure()); buffer << "CREATE TABLE " << backQuoteIfNeed(name) << '.' << backQuoteIfNeed(table_name) << " ("; buffer << StorageDictionary::generateNamesAndTypesDescription(names_and_types.begin(), names_and_types.end()); buffer << ") Engine = Dictionary(" << backQuoteIfNeed(table_name) << ")"; } ParserCreateQuery parser; const char * pos = query.data(); std::string error_message; auto ast = tryParseQuery(parser, pos, pos + query.size(), error_message, /* hilite = */ false, "", /* allow_multi_statements = */ false, 0); if (!ast && throw_on_error) throw Exception(error_message, ErrorCodes::SYNTAX_ERROR); return ast; }
void ASTDropQuery::formatQueryImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const { settings.ostr << (settings.hilite ? hilite_keyword : ""); if (kind == ASTDropQuery::Kind::Drop) settings.ostr << "DROP "; else if (kind == ASTDropQuery::Kind::Detach) settings.ostr << "DETACH "; else if (kind == ASTDropQuery::Kind::Truncate) settings.ostr << "TRUNCATE "; else throw Exception("Not supported kind of drop query.", ErrorCodes::SYNTAX_ERROR); settings.ostr << ((table.empty() && !database.empty()) ? "DATABASE " : "TABLE "); if (if_exists) settings.ostr << "IF EXISTS "; settings.ostr << (settings.hilite ? hilite_none : ""); if (table.empty() && !database.empty()) settings.ostr << backQuoteIfNeed(database); else settings.ostr << (!database.empty() ? backQuoteIfNeed(database) + "." : "") << backQuoteIfNeed(table); formatOnCluster(settings); }
void ASTAlterQuery::formatQueryImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const { frame.need_parens = false; std::string indent_str = settings.one_line ? "" : std::string(4u * frame.indent, ' '); settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "ALTER TABLE " << (settings.hilite ? hilite_none : ""); if (!table.empty()) { if (!database.empty()) { settings.ostr << indent_str << backQuoteIfNeed(database); settings.ostr << "."; } settings.ostr << indent_str << backQuoteIfNeed(table); } formatOnCluster(settings); settings.ostr << settings.nl_or_ws; FormatStateStacked frame_nested = frame; frame_nested.need_parens = false; ++frame_nested.indent; static_cast<IAST *>(command_list)->formatImpl(settings, state, frame_nested); }
DatabaseAndTable InterpreterDropQuery::tryGetDatabaseAndTable(String & database_name, String & table_name, bool if_exists) { DatabasePtr database = tryGetDatabase(database_name, if_exists); if (database) { StoragePtr table = database->tryGetTable(context, table_name); if (!table && !if_exists) throw Exception("Table " + backQuoteIfNeed(database_name) + "." + backQuoteIfNeed(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE); return {std::move(database), std::move(table)}; } return {}; }
void PushingToViewsBlockOutputStream::process(const Block & block, size_t view_num) { auto & view = views[view_num]; try { BlockInputStreamPtr from = std::make_shared<OneBlockInputStream>(block); InterpreterSelectQuery select(view.query, *views_context, from); BlockInputStreamPtr in = std::make_shared<MaterializingBlockInputStream>(select.execute().in); /// Squashing is needed here because the materialized view query can generate a lot of blocks /// even when only one block is inserted into the parent table (e.g. if the query is a GROUP BY /// and two-level aggregation is triggered). in = std::make_shared<SquashingBlockInputStream>( in, context.getSettingsRef().min_insert_block_size_rows, context.getSettingsRef().min_insert_block_size_bytes); in->readPrefix(); while (Block result_block = in->read()) { Nested::validateArraySizes(result_block); view.out->write(result_block); } in->readSuffix(); } catch (Exception & ex) { ex.addMessage("while pushing to view " + backQuoteIfNeed(view.database) + "." + backQuoteIfNeed(view.table)); throw; } }
void ASTQueryWithOnCluster::formatOnCluster(const IAST::FormatSettings & settings) const { if (!cluster.empty()) { settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " ON CLUSTER " << (settings.hilite ? IAST::hilite_none : "") << backQuoteIfNeed(cluster); } }
NamesAndTypesList getStructureOfRemoteTable( const Cluster & cluster, const std::string & database, const std::string & table, const Context & context) { /// Запрос на описание таблицы String query = "DESC TABLE " + backQuoteIfNeed(database) + "." + backQuoteIfNeed(table); Settings settings = context.getSettings(); NamesAndTypesList res; /// Отправляем на первый попавшийся удалённый шард. const auto & shard_info = cluster.getAnyShardInfo(); if (shard_info.isLocal()) return context.getTable(database, table)->getColumnsList(); ConnectionPoolPtr pool = shard_info.pool; BlockInputStreamPtr input = std::make_shared<RemoteBlockInputStream>( pool.get(), query, &settings, nullptr, Tables(), QueryProcessingStage::Complete, context); input->readPrefix(); const DataTypeFactory & data_type_factory = DataTypeFactory::instance(); while (Block current = input->read()) { ColumnPtr name = current.getByName("name").column; ColumnPtr type = current.getByName("type").column; size_t size = name->size(); for (size_t i = 0; i < size; ++i) { String column_name = (*name)[i].get<const String &>(); String data_type_name = (*type)[i].get<const String &>(); res.emplace_back(column_name, data_type_factory.get(data_type_name)); } } return res; }
ASTPtr DatabaseDictionary::getCreateDatabaseQuery(const Context & /*context*/) const { String query; { WriteBufferFromString buffer(query); buffer << "CREATE DATABASE " << backQuoteIfNeed(name) << " ENGINE = Dictionary"; } ParserCreateQuery parser; return parseQuery(parser, query.data(), query.data() + query.size(), "", 0); }
void loadMetadata(Context & context) { String path = context.getPath() + "metadata"; /** There may exist 'force_restore_data' file, that means, * skip safety threshold on difference of data parts while initializing tables. * This file is deleted after successful loading of tables. * (flag is "one-shot") */ Poco::File force_restore_data_flag_file(context.getFlagsPath() + "force_restore_data"); bool has_force_restore_data_flag = force_restore_data_flag_file.exists(); /// For parallel tables loading. ThreadPool thread_pool(SettingMaxThreads().getAutoValue()); /// Loop over databases. Poco::DirectoryIterator dir_end; for (Poco::DirectoryIterator it(path); it != dir_end; ++it) { if (!it->isDirectory()) continue; /// For '.svn', '.gitignore' directory and similar. if (it.name().at(0) == '.') continue; String database = unescapeForFileName(it.name()); /// There may exist .sql file with database creation statement. /// Or, if it is absent, then database with default engine is created. String database_attach_query; String database_metadata_file = it->path() + ".sql"; if (Poco::File(database_metadata_file).exists()) { ReadBufferFromFile in(database_metadata_file, 1024); readStringUntilEOF(database_attach_query, in); } else database_attach_query = "ATTACH DATABASE " + backQuoteIfNeed(database); executeCreateQuery(database_attach_query, context, database, it->path(), thread_pool, has_force_restore_data_flag); } thread_pool.wait(); if (has_force_restore_data_flag) force_restore_data_flag_file.remove(); }
ASTPtr DatabaseOrdinary::getCreateDatabaseQuery(const Context & /*context*/) const { ASTPtr ast; auto database_metadata_path = detail::getDatabaseMetadataPath(metadata_path); ast = getCreateQueryFromMetadata(database_metadata_path, name, true); if (!ast) { /// Handle databases (such as default) for which there are no database.sql files. String query = "CREATE DATABASE " + backQuoteIfNeed(name) + " ENGINE = Ordinary"; ParserCreateQuery parser; ast = parseQuery(parser, query.data(), query.data() + query.size(), "", 0); } return ast; }
ColumnsDescription InterpreterCreateQuery::setColumns( ASTCreateQuery & create, const Block & as_select_sample, const StoragePtr & as_storage) const { ColumnsDescription res; if (create.columns) { res = getColumnsDescription(*create.columns, context); } else if (!create.as_table.empty()) { res = as_storage->getColumns(); } else if (create.select) { for (size_t i = 0; i < as_select_sample.columns(); ++i) res.ordinary.emplace_back(as_select_sample.safeGetByPosition(i).name, as_select_sample.safeGetByPosition(i).type); } else throw Exception("Incorrect CREATE query: required list of column descriptions or AS section or SELECT.", ErrorCodes::INCORRECT_QUERY); /// Even if query has list of columns, canonicalize it (unfold Nested columns). ASTPtr new_columns = formatColumns(res); if (create.columns) create.replace(create.columns, new_columns); else create.set(create.columns, new_columns); /// Check for duplicates std::set<String> all_columns; auto check_column_already_exists = [&all_columns](const NameAndTypePair & column_name_and_type) { if (!all_columns.emplace(column_name_and_type.name).second) throw Exception("Column " + backQuoteIfNeed(column_name_and_type.name) + " already exists", ErrorCodes::DUPLICATE_COLUMN); }; for (const auto & elem : res.ordinary) check_column_already_exists(elem); for (const auto & elem : res.materialized) check_column_already_exists(elem); for (const auto & elem : res.aliases) check_column_already_exists(elem); return res; }
static void processImpl(const ASTPtr & ast, CollectAliases::Aliases & aliases, CollectAliases::Kind kind, size_t keep_kind_for_depth) { String alias = ast->tryGetAlias(); if (!alias.empty()) { auto it_inserted = aliases.emplace(alias, CollectAliases::AliasInfo(ast, kind)); if (!it_inserted.second && ast->getTreeHash() != it_inserted.first->second.node->getTreeHash()) { std::stringstream message; message << "Different expressions with the same alias " << backQuoteIfNeed(alias) << ":\n"; formatAST(*it_inserted.first->second.node, message, 0, false, true); message << "\nand\n"; formatAST(*ast, message, 0, false, true); message << "\n"; throw Exception(message.str(), ErrorCodes::MULTIPLE_EXPRESSIONS_FOR_ALIAS); } } for (auto & child : ast->children) { if (typeid_cast<const ASTSelectQuery *>(child.get())) { /// Don't go into subqueries. } else if (typeid_cast<const ASTTableExpression *>(child.get())) { processImpl(child, aliases, CollectAliases::Kind::Table, 1); } else if (typeid_cast<const ASTArrayJoin *>(child.get())) { /// ASTArrayJoin -> ASTExpressionList -> element of expression AS alias processImpl(child, aliases, CollectAliases::Kind::ArrayJoin, 3); } else if (keep_kind_for_depth > 0) { processImpl(child, aliases, kind, keep_kind_for_depth - 1); } else { processImpl(child, aliases, CollectAliases::Kind::Expression, 0); } } }
void loadMetadata(Context & context) { String path = context.getPath() + "metadata"; /// Используется для параллельной загрузки таблиц. ThreadPool thread_pool(SettingMaxThreads().getAutoValue()); /// Цикл по базам данных Poco::DirectoryIterator dir_end; for (Poco::DirectoryIterator it(path); it != dir_end; ++it) { if (!it->isDirectory()) continue; /// Для директории .svn if (it.name().at(0) == '.') continue; String database = unescapeForFileName(it.name()); /// Для базы данных может быть расположен .sql файл, где описан запрос на её создание. /// А если такого файла нет, то создаётся база данных с движком по-умолчанию. String database_attach_query; String database_metadata_file = it->path() + ".sql"; if (Poco::File(database_metadata_file).exists()) { ReadBufferFromFile in(database_metadata_file, 1024); readStringUntilEOF(database_attach_query, in); } else database_attach_query = "ATTACH DATABASE " + backQuoteIfNeed(database); executeCreateQuery(database_attach_query, context, database, it->path(), thread_pool); } thread_pool.wait(); }
void ReplicasStatusHandler::handleRequest(Poco::Net::HTTPServerRequest & request, Poco::Net::HTTPServerResponse & response) { try { HTMLForm params(request); /// Даже в случае, когда отставание небольшое, выводить подробную информацию об отставании. bool verbose = params.get("verbose", "") == "1"; const MergeTreeSettings & settings = context.getMergeTreeSettings(); bool ok = true; std::stringstream message; auto databases = context.getDatabases(); /// Перебираем все реплицируемые таблицы. for (const auto & db : databases) { for (auto iterator = db.second->getIterator(); iterator->isValid(); iterator->next()) { auto & table = iterator->table(); StorageReplicatedMergeTree * table_replicated = typeid_cast<StorageReplicatedMergeTree *>(table.get()); if (!table_replicated) continue; time_t absolute_delay = 0; time_t relative_delay = 0; table_replicated->getReplicaDelays(absolute_delay, relative_delay); if ((settings.min_absolute_delay_to_close && absolute_delay >= static_cast<time_t>(settings.min_absolute_delay_to_close)) || (settings.min_relative_delay_to_close && relative_delay >= static_cast<time_t>(settings.min_relative_delay_to_close))) ok = false; message << backQuoteIfNeed(db.first) << "." << backQuoteIfNeed(iterator->name()) << ":\tAbsolute delay: " << absolute_delay << ". Relative delay: " << relative_delay << ".\n"; } } setResponseDefaultHeaders(response); if (ok && !verbose) { const char * data = "Ok.\n"; response.sendBuffer(data, strlen(data)); } else { response.send() << message.rdbuf(); } } catch (...) { tryLogCurrentException("ReplicasStatusHandler"); try { response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR); if (!response.sent()) { /// Ещё ничего не отправляли, и даже не знаем, нужно ли сжимать ответ. response.send() << getCurrentExceptionMessage(false) << std::endl; } } catch (...) { LOG_ERROR((&Logger::get("ReplicasStatusHandler")), "Cannot send exception to client"); } } }
void ASTAlterQuery::formatQueryImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const { frame.need_parens = false; std::string indent_str = settings.one_line ? "" : std::string(4u * frame.indent, ' '); settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "ALTER TABLE " << (settings.hilite ? hilite_none : ""); if (!table.empty()) { if (!database.empty()) { settings.ostr << indent_str << backQuoteIfNeed(database); settings.ostr << "."; } settings.ostr << indent_str << backQuoteIfNeed(table); } formatOnCluster(settings); settings.ostr << settings.nl_or_ws; for (size_t i = 0; i < parameters.size(); ++i) { const ASTAlterQuery::Parameters & p = parameters[i]; if (p.type == ASTAlterQuery::ADD_COLUMN) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "ADD COLUMN " << (settings.hilite ? hilite_none : ""); p.col_decl->formatImpl(settings, state, frame); /// AFTER if (p.column) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << " AFTER " << (settings.hilite ? hilite_none : ""); p.column->formatImpl(settings, state, frame); } } else if (p.type == ASTAlterQuery::DROP_COLUMN) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << (p.clear_column ? "CLEAR " : "DROP ") << "COLUMN " << (settings.hilite ? hilite_none : ""); p.column->formatImpl(settings, state, frame); if (p.partition) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str<< " IN PARTITION " << (settings.hilite ? hilite_none : ""); p.partition->formatImpl(settings, state, frame); } } else if (p.type == ASTAlterQuery::MODIFY_COLUMN) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "MODIFY COLUMN " << (settings.hilite ? hilite_none : ""); p.col_decl->formatImpl(settings, state, frame); } else if (p.type == ASTAlterQuery::MODIFY_PRIMARY_KEY) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "MODIFY PRIMARY KEY " << (settings.hilite ? hilite_none : ""); settings.ostr << "("; p.primary_key->formatImpl(settings, state, frame); settings.ostr << ")"; } else if (p.type == ASTAlterQuery::DROP_PARTITION) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << (p.detach ? "DETACH" : "DROP") << " PARTITION " << (settings.hilite ? hilite_none : ""); p.partition->formatImpl(settings, state, frame); } else if (p.type == ASTAlterQuery::ATTACH_PARTITION) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "ATTACH " << (p.part ? "PART " : "PARTITION ") << (settings.hilite ? hilite_none : ""); p.partition->formatImpl(settings, state, frame); } else if (p.type == ASTAlterQuery::FETCH_PARTITION) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "FETCH " << "PARTITION " << (settings.hilite ? hilite_none : ""); p.partition->formatImpl(settings, state, frame); settings.ostr << (settings.hilite ? hilite_keyword : "") << " FROM " << (settings.hilite ? hilite_none : "") << std::quoted(p.from, '\''); } else if (p.type == ASTAlterQuery::FREEZE_PARTITION) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "FREEZE PARTITION " << (settings.hilite ? hilite_none : ""); p.partition->formatImpl(settings, state, frame); if (!p.with_name.empty()) { settings.ostr << " " << (settings.hilite ? hilite_keyword : "") << "WITH NAME" << (settings.hilite ? hilite_none : "") << " " << std::quoted(p.with_name, '\''); } } else throw Exception("Unexpected type of ALTER", ErrorCodes::UNEXPECTED_AST_STRUCTURE); std::string comma = (i < (parameters.size() -1) ) ? "," : ""; settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << comma << (settings.hilite ? hilite_none : ""); settings.ostr << settings.nl_or_ws; } }
void AsynchronousMetrics::update() { { if (auto mark_cache = context.getMarkCache()) { set("MarkCacheBytes", mark_cache->weight()); set("MarkCacheFiles", mark_cache->count()); } } { if (auto uncompressed_cache = context.getUncompressedCache()) { set("UncompressedCacheBytes", uncompressed_cache->weight()); set("UncompressedCacheCells", uncompressed_cache->count()); } } { auto databases = context.getDatabases(); size_t max_queue_size = 0; size_t max_inserts_in_queue = 0; size_t max_merges_in_queue = 0; size_t sum_queue_size = 0; size_t sum_inserts_in_queue = 0; size_t sum_merges_in_queue = 0; size_t max_absolute_delay = 0; size_t max_relative_delay = 0; size_t max_part_count_for_partition = 0; for (const auto & db : databases) { for (auto iterator = db.second->getIterator(); iterator->isValid(); iterator->next()) { auto & table = iterator->table(); StorageMergeTree * table_merge_tree = typeid_cast<StorageMergeTree *>(table.get()); StorageReplicatedMergeTree * table_replicated_merge_tree = typeid_cast<StorageReplicatedMergeTree *>(table.get()); if (table_replicated_merge_tree) { StorageReplicatedMergeTree::Status status; table_replicated_merge_tree->getStatus(status, false); calculateMaxAndSum(max_queue_size, sum_queue_size, status.queue.queue_size); calculateMaxAndSum(max_inserts_in_queue, sum_inserts_in_queue, status.queue.inserts_in_queue); calculateMaxAndSum(max_merges_in_queue, sum_merges_in_queue, status.queue.merges_in_queue); try { time_t absolute_delay = 0; time_t relative_delay = 0; table_replicated_merge_tree->getReplicaDelays(absolute_delay, relative_delay); calculateMax(max_absolute_delay, absolute_delay); calculateMax(max_relative_delay, relative_delay); } catch (...) { tryLogCurrentException(__PRETTY_FUNCTION__, "Cannot get replica delay for table: " + backQuoteIfNeed(db.first) + "." + backQuoteIfNeed(iterator->name())); } calculateMax(max_part_count_for_partition, table_replicated_merge_tree->getData().getMaxPartsCountForMonth()); } if (table_merge_tree) { calculateMax(max_part_count_for_partition, table_merge_tree->getData().getMaxPartsCountForMonth()); } } } set("ReplicasMaxQueueSize", max_queue_size); set("ReplicasMaxInsertsInQueue", max_inserts_in_queue); set("ReplicasMaxMergesInQueue", max_merges_in_queue); set("ReplicasSumQueueSize", sum_queue_size); set("ReplicasSumInsertsInQueue", sum_inserts_in_queue); set("ReplicasSumMergesInQueue", sum_merges_in_queue); set("ReplicasMaxAbsoluteDelay", max_absolute_delay); set("ReplicasMaxRelativeDelay", max_relative_delay); set("MaxPartCountForPartition", max_part_count_for_partition); } #if USE_TCMALLOC { /// tcmalloc related metrics. Remove if you switch to different allocator. MallocExtension & malloc_extension = *MallocExtension::instance(); auto malloc_metrics = { "generic.current_allocated_bytes", "generic.heap_size", "tcmalloc.current_total_thread_cache_bytes", "tcmalloc.central_cache_free_bytes", "tcmalloc.transfer_cache_free_bytes", "tcmalloc.thread_cache_free_bytes", "tcmalloc.pageheap_free_bytes", "tcmalloc.pageheap_unmapped_bytes", }; for (auto malloc_metric : malloc_metrics) { size_t value = 0; if (malloc_extension.GetNumericProperty(malloc_metric, &value)) set(malloc_metric, value); } } #endif /// Add more metrics as you wish. }
void ASTAlterCommand::formatImpl( const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const { std::string indent_str = settings.one_line ? "" : std::string(4 * frame.indent, ' '); if (type == ASTAlterCommand::ADD_COLUMN) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "ADD COLUMN " << (if_not_exists ? "IF NOT EXISTS " : "") << (settings.hilite ? hilite_none : ""); col_decl->formatImpl(settings, state, frame); /// AFTER if (column) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << " AFTER " << (settings.hilite ? hilite_none : ""); column->formatImpl(settings, state, frame); } } else if (type == ASTAlterCommand::DROP_COLUMN) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << (clear_column ? "CLEAR " : "DROP ") << "COLUMN " << (if_exists ? "IF EXISTS " : "") << (settings.hilite ? hilite_none : ""); column->formatImpl(settings, state, frame); if (partition) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str<< " IN PARTITION " << (settings.hilite ? hilite_none : ""); partition->formatImpl(settings, state, frame); } } else if (type == ASTAlterCommand::MODIFY_COLUMN) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "MODIFY COLUMN " << (if_exists ? "IF EXISTS " : "") << (settings.hilite ? hilite_none : ""); col_decl->formatImpl(settings, state, frame); } else if (type == ASTAlterCommand::MODIFY_ORDER_BY) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "MODIFY ORDER BY " << (settings.hilite ? hilite_none : ""); order_by->formatImpl(settings, state, frame); } else if (type == ASTAlterCommand::ADD_INDEX) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "ADD INDEX " << (if_not_exists ? "IF NOT EXISTS " : "") << (settings.hilite ? hilite_none : ""); index_decl->formatImpl(settings, state, frame); /// AFTER if (index) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << " AFTER " << (settings.hilite ? hilite_none : ""); index->formatImpl(settings, state, frame); } } else if (type == ASTAlterCommand::DROP_INDEX) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "DROP INDEX " << (if_exists ? "IF EXISTS " : "") << (settings.hilite ? hilite_none : ""); index->formatImpl(settings, state, frame); } else if (type == ASTAlterCommand::DROP_PARTITION) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << (detach ? "DETACH" : "DROP") << " PARTITION " << (settings.hilite ? hilite_none : ""); partition->formatImpl(settings, state, frame); } else if (type == ASTAlterCommand::ATTACH_PARTITION) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "ATTACH " << (part ? "PART " : "PARTITION ") << (settings.hilite ? hilite_none : ""); partition->formatImpl(settings, state, frame); } else if (type == ASTAlterCommand::REPLACE_PARTITION) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << (replace ? "REPLACE" : "ATTACH") << " PARTITION " << (settings.hilite ? hilite_none : ""); partition->formatImpl(settings, state, frame); settings.ostr << (settings.hilite ? hilite_keyword : "") << " FROM " << (settings.hilite ? hilite_none : ""); if (!from_database.empty()) { settings.ostr << (settings.hilite ? hilite_identifier : "") << backQuoteIfNeed(from_database) << (settings.hilite ? hilite_none : "") << "."; } settings.ostr << (settings.hilite ? hilite_identifier : "") << backQuoteIfNeed(from_table) << (settings.hilite ? hilite_none : ""); } else if (type == ASTAlterCommand::FETCH_PARTITION) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "FETCH " << "PARTITION " << (settings.hilite ? hilite_none : ""); partition->formatImpl(settings, state, frame); settings.ostr << (settings.hilite ? hilite_keyword : "") << " FROM " << (settings.hilite ? hilite_none : "") << std::quoted(from, '\''); } else if (type == ASTAlterCommand::FREEZE_PARTITION) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "FREEZE PARTITION " << (settings.hilite ? hilite_none : ""); partition->formatImpl(settings, state, frame); if (!with_name.empty()) { settings.ostr << " " << (settings.hilite ? hilite_keyword : "") << "WITH NAME" << (settings.hilite ? hilite_none : "") << " " << std::quoted(with_name, '\''); } } else if (type == ASTAlterCommand::FREEZE_ALL) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "FREEZE"; if (!with_name.empty()) { settings.ostr << " " << (settings.hilite ? hilite_keyword : "") << "WITH NAME" << (settings.hilite ? hilite_none : "") << " " << std::quoted(with_name, '\''); } } else if (type == ASTAlterCommand::DELETE) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "DELETE WHERE " << (settings.hilite ? hilite_none : ""); predicate->formatImpl(settings, state, frame); } else if (type == ASTAlterCommand::UPDATE) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "UPDATE " << (settings.hilite ? hilite_none : ""); update_assignments->formatImpl(settings, state, frame); settings.ostr << (settings.hilite ? hilite_keyword : "") << " WHERE " << (settings.hilite ? hilite_none : ""); predicate->formatImpl(settings, state, frame); } else if (type == ASTAlterCommand::COMMENT_COLUMN) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "COMMENT COLUMN " << (settings.hilite ? hilite_none : ""); column->formatImpl(settings, state, frame); settings.ostr << " " << (settings.hilite ? hilite_none : ""); comment->formatImpl(settings, state, frame); } else throw Exception("Unexpected type of ALTER", ErrorCodes::UNEXPECTED_AST_STRUCTURE); }