#include #include #include #include namespace DB { namespace { class CreateUniqueTableAliasesVisitor : public InDepthQueryTreeVisitorWithContext { public: using Base = InDepthQueryTreeVisitorWithContext; explicit CreateUniqueTableAliasesVisitor(const ContextPtr & context) : Base(context) {} void enterImpl(QueryTreeNodePtr & node) { switch (node->getNodeType()) { case QueryTreeNodeType::QUERY: [[fallthrough]]; case QueryTreeNodeType::UNION: { if (getSubqueryDepth() == 1) { node->removeAlias(); break; } [[fallthrough]]; } case QueryTreeNodeType::TABLE: [[fallthrough]]; case QueryTreeNodeType::TABLE_FUNCTION: { auto & alias = table_expression_to_alias[node]; if (alias.empty()) { alias = fmt::format("__table{}", table_expression_to_alias.size()); node->setAlias(alias); } break; } default: break; } } private: // We need to use raw pointer as a key, not a QueryTreeNodePtrWithHash. std::unordered_map table_expression_to_alias; }; } void createUniqueTableAliases(QueryTreeNodePtr & node, const ContextPtr & context) { CreateUniqueTableAliasesVisitor(context).visit(node); } }