2020-10-28 01:29:09 +00:00
|
|
|
#include <list>
|
2020-10-26 09:33:34 +00:00
|
|
|
#include <memory>
|
2018-02-25 00:50:53 +00:00
|
|
|
#include <Parsers/ExpressionListParsers.h>
|
|
|
|
#include <Parsers/ParserSelectWithUnionQuery.h>
|
|
|
|
#include <Parsers/ASTSelectWithUnionQuery.h>
|
2018-03-13 00:35:20 +00:00
|
|
|
#include <Parsers/ParserUnionQueryElement.h>
|
|
|
|
#include <Parsers/ASTExpressionList.h>
|
|
|
|
#include <Common/typeid_cast.h>
|
2018-02-25 00:50:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
2018-04-19 03:08:22 +00:00
|
|
|
static void getSelectsFromUnionListNode(ASTPtr & ast_select, ASTs & selects)
|
|
|
|
{
|
2019-03-11 13:22:51 +00:00
|
|
|
if (auto * inner_union = ast_select->as<ASTSelectWithUnionQuery>())
|
2018-04-19 03:08:22 +00:00
|
|
|
{
|
|
|
|
for (auto & child : inner_union->list_of_selects->children)
|
2020-10-28 01:29:09 +00:00
|
|
|
{
|
2018-04-19 03:08:22 +00:00
|
|
|
getSelectsFromUnionListNode(child, selects);
|
2020-10-28 01:29:09 +00:00
|
|
|
}
|
2018-04-19 03:08:22 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
selects.push_back(std::move(ast_select));
|
|
|
|
}
|
|
|
|
|
2018-02-25 06:34:20 +00:00
|
|
|
bool ParserSelectWithUnionQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
2018-02-25 00:50:53 +00:00
|
|
|
{
|
2020-10-28 01:29:09 +00:00
|
|
|
std::cout << "\n\n in ParserSelectWithUnionQuery\n\n";
|
2018-02-25 00:50:53 +00:00
|
|
|
ASTPtr list_node;
|
|
|
|
|
2020-10-26 09:33:34 +00:00
|
|
|
ParserUnionList parser(
|
|
|
|
std::make_unique<ParserUnionQueryElement>(),
|
|
|
|
std::make_unique<ParserKeyword>("UNION"),
|
|
|
|
std::make_unique<ParserKeyword>("ALL"),
|
|
|
|
std::make_unique<ParserKeyword>("DISTINCT"));
|
2020-10-24 13:18:04 +00:00
|
|
|
|
2020-10-26 09:33:34 +00:00
|
|
|
if (!parser.parse(pos, list_node, expected))
|
|
|
|
return false;
|
2018-02-25 00:50:53 +00:00
|
|
|
|
2018-03-13 00:35:20 +00:00
|
|
|
auto select_with_union_query = std::make_shared<ASTSelectWithUnionQuery>();
|
2018-02-25 07:39:45 +00:00
|
|
|
|
2018-03-13 00:35:20 +00:00
|
|
|
node = select_with_union_query;
|
|
|
|
select_with_union_query->list_of_selects = std::make_shared<ASTExpressionList>();
|
|
|
|
select_with_union_query->children.push_back(select_with_union_query->list_of_selects);
|
2020-10-28 01:29:09 +00:00
|
|
|
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());
|
2020-10-26 09:33:34 +00:00
|
|
|
select_with_union_query->union_modes = parser.getUnionModes();
|
2018-03-13 00:35:20 +00:00
|
|
|
|
2020-10-28 01:29:09 +00:00
|
|
|
/// 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<ASTExpressionList>();
|
|
|
|
|
2018-03-13 00:35:20 +00:00
|
|
|
for (auto & child : list_node->children)
|
2020-10-28 01:29:09 +00:00
|
|
|
{
|
|
|
|
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";
|
2018-02-25 07:39:45 +00:00
|
|
|
|
2018-02-25 00:50:53 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|