#include #include #include #include #include #include #include #include namespace DB { ASTPtr ASTTableOverride::clone() const { auto res = std::make_shared(*this); res->children.clear(); res->table_name = table_name; if (columns) res->set(res->columns, columns->clone()); if (storage) res->set(res->storage, storage->clone()); return res; } void ASTTableOverride::formatImpl(const FormatSettings & settings_, FormatState & state, FormatStateStacked frame) const { FormatSettings settings = settings_; settings.always_quote_identifiers = true; String nl_or_nothing = settings.one_line ? "" : "\n"; String nl_or_ws = settings.one_line ? " " : "\n"; String hl_keyword = settings.hilite ? hilite_keyword : ""; String hl_none = settings.hilite ? hilite_none : ""; settings.ostr << hl_keyword << "TABLE OVERRIDE " << hl_none; ASTIdentifier(table_name).formatImpl(settings, state, frame); if (!columns && (!storage || storage->children.empty())) return; auto override_frame = frame; ++override_frame.indent; settings.ostr << nl_or_ws << '(' << nl_or_nothing; String indent_str = settings.one_line ? "" : String(4 * override_frame.indent, ' '); size_t override_elems = 0; if (columns) { FormatStateStacked columns_frame = override_frame; columns_frame.expression_list_always_start_on_new_line = true; settings.ostr << indent_str << hl_keyword << "COLUMNS" << hl_none << nl_or_ws << indent_str << "("; columns->formatImpl(settings, state, columns_frame); settings.ostr << nl_or_nothing << indent_str << ")"; ++override_elems; } if (storage) { const auto & format_storage_elem = [&](IAST * elem, const String & elem_name) { if (elem) { settings.ostr << (override_elems++ ? nl_or_ws : "") << indent_str << hl_keyword << elem_name << hl_none << ' '; elem->formatImpl(settings, state, override_frame); } }; format_storage_elem(storage->partition_by, "PARTITION BY"); format_storage_elem(storage->primary_key, "PRIMARY KEY"); format_storage_elem(storage->order_by, "ORDER BY"); format_storage_elem(storage->sample_by, "SAMPLE BY"); format_storage_elem(storage->ttl_table, "TTL"); } settings.ostr << nl_or_nothing << ')'; } ASTPtr ASTTableOverrideList::clone() const { auto res = std::make_shared(*this); res->cloneChildren(); return res; } ASTPtr ASTTableOverrideList::tryGetTableOverride(const String & name) const { auto it = positions.find(name); if (it == positions.end()) return nullptr; return children[it->second]; } void ASTTableOverrideList::setTableOverride(const String & name, const ASTPtr ast) { auto it = positions.find(name); if (it == positions.end()) { positions[name] = children.size(); children.emplace_back(ast); } else { children[it->second] = ast; } } void ASTTableOverrideList::removeTableOverride(const String & name) { if (hasOverride(name)) { size_t pos = positions[name]; children.erase(children.begin() + pos); positions.erase(name); for (auto & pr : positions) if (pr.second > pos) --pr.second; } } bool ASTTableOverrideList::hasOverride(const String & name) const { return positions.count(name); } void ASTTableOverrideList::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const { if (frame.expression_list_prepend_whitespace) settings.ostr << ' '; for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it) { if (it != children.begin()) { settings.ostr << (settings.one_line ? ", " : ",\n"); } (*it)->formatImpl(settings, state, frame); } } }