#include #include #include #include #include #include #include #include namespace DB { static void getSelectsFromUnionListNode(ASTPtr & ast_select, ASTs & selects) { if (auto * inner_union = ast_select->as()) { for (auto & child : inner_union->list_of_selects->children) { getSelectsFromUnionListNode(child, selects); } return; } selects.push_back(std::move(ast_select)); } bool ParserSelectWithUnionQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) { std::cout << "\n\n in ParserSelectWithUnionQuery\n\n"; ASTPtr list_node; ParserUnionList parser( std::make_unique(), std::make_unique("UNION"), std::make_unique("ALL"), std::make_unique("DISTINCT")); if (!parser.parse(pos, list_node, expected)) return false; auto select_with_union_query = std::make_shared(); node = select_with_union_query; select_with_union_query->list_of_selects = std::make_shared(); select_with_union_query->children.push_back(select_with_union_query->list_of_selects); select_with_union_query->list_of_selects->children.insert( select_with_union_query->list_of_selects->children.begin(), list_node->children.begin(), list_node->children.end()); select_with_union_query->union_modes = parser.getUnionModes(); /// NOTE: We cann't simply flatten inner union query now, since we may have different union mode in query, /// so flatten may change it's semantics. For example: /// flatten `SELECT 1 UNION (SELECT 1 UNION ALL SELETC 1)` -> `SELECT 1 UNION SELECT 1 UNION ALL SELECT 1` /// We can use a non-flatten AST to help build QueryPlan in InterpreterSelectWithUnionQuery select_with_union_query->flatten_nodes_list = std::make_shared(); for (auto & child : list_node->children) { getSelectsFromUnionListNode(child, select_with_union_query->flatten_nodes_list->children); } std::cout << "\n\n after ParserSelectWithUnionQuery\n\n"; std::cout << "\n\n flatten_nodes.size =" << select_with_union_query->flatten_nodes_list->children.size() << "\n\n"; return true; } }