fix
This commit is contained in:
feng lv 2021-02-26 12:04:11 +00:00
parent 731faeadbf
commit 4c30c10092
5 changed files with 170 additions and 15 deletions

View File

@ -20,7 +20,7 @@ void NormalizeSelectWithUnionQueryMatcher::getSelectsFromUnionListNode(ASTPtr &
return; return;
} }
selects.push_back(std::move(ast_select)); selects.push_back(ast_select);
} }
void NormalizeSelectWithUnionQueryMatcher::visit(ASTPtr & ast, Data & data) void NormalizeSelectWithUnionQueryMatcher::visit(ASTPtr & ast, Data & data)
@ -53,15 +53,16 @@ void NormalizeSelectWithUnionQueryMatcher::visit(ASTSelectWithUnionQuery & ast,
if (union_modes[i] == ASTSelectWithUnionQuery::Mode::ALL) if (union_modes[i] == ASTSelectWithUnionQuery::Mode::ALL)
{ {
if (auto * inner_union = select_list[i + 1]->as<ASTSelectWithUnionQuery>()) if (auto * inner_union = select_list[i + 1]->as<ASTSelectWithUnionQuery>();
inner_union && inner_union->union_mode == ASTSelectWithUnionQuery::Mode::ALL)
{ {
/// Inner_union is an UNION ALL list, just lift up /// Inner_union is an UNION ALL list, just lift up
for (auto child = inner_union->list_of_selects->children.rbegin(); child != inner_union->list_of_selects->children.rend(); for (auto child = inner_union->list_of_selects->children.rbegin(); child != inner_union->list_of_selects->children.rend();
++child) ++child)
selects.push_back(std::move(*child)); selects.push_back(*child);
} }
else else
selects.push_back(std::move(select_list[i + 1])); selects.push_back(select_list[i + 1]);
} }
/// flatten all left nodes and current node to a UNION DISTINCT list /// flatten all left nodes and current node to a UNION DISTINCT list
else if (union_modes[i] == ASTSelectWithUnionQuery::Mode::DISTINCT) else if (union_modes[i] == ASTSelectWithUnionQuery::Mode::DISTINCT)
@ -85,15 +86,23 @@ void NormalizeSelectWithUnionQueryMatcher::visit(ASTSelectWithUnionQuery & ast,
/// No UNION DISTINCT or only one child in select_list /// No UNION DISTINCT or only one child in select_list
if (i == -1) if (i == -1)
{ {
if (auto * inner_union = select_list[0]->as<ASTSelectWithUnionQuery>()) if (auto * inner_union = select_list[0]->as<ASTSelectWithUnionQuery>();
inner_union && inner_union->union_mode == ASTSelectWithUnionQuery::Mode::ALL)
{ {
/// Inner_union is an UNION ALL list, just lift it up /// Inner_union is an UNION ALL list, just lift it up
for (auto child = inner_union->list_of_selects->children.rbegin(); child != inner_union->list_of_selects->children.rend(); for (auto child = inner_union->list_of_selects->children.rbegin(); child != inner_union->list_of_selects->children.rend();
++child) ++child)
selects.push_back(std::move(*child)); selects.push_back(*child);
} }
else else
selects.push_back(std::move(select_list[0])); selects.push_back(select_list[0]);
}
/// Just one union type child, lift it up
if (selects.size() == 1 && selects[0]->as<ASTSelectWithUnionQuery>())
{
ast = *(selects[0]->as<ASTSelectWithUnionQuery>());
return;
} }
// reverse children list // reverse children list

View File

@ -480,13 +480,6 @@ static std::tuple<ASTPtr, BlockIO> executeQueryImpl(
NormalizeSelectWithUnionQueryVisitor::Data data{context.getSettingsRef().union_default_mode}; NormalizeSelectWithUnionQueryVisitor::Data data{context.getSettingsRef().union_default_mode};
NormalizeSelectWithUnionQueryVisitor{data}.visit(ast); NormalizeSelectWithUnionQueryVisitor{data}.visit(ast);
/// After normalization, if it only has one ASTSelectWithUnionQuery child,
/// we can lift it up, this can reduce one unnecessary recursion later in interpreter phase
auto select_union = ast->as<ASTSelectWithUnionQuery>();
if (select_union && select_union->list_of_selects->children.size() == 1
&& select_union->list_of_selects->children.at(0)->as<ASTSelectWithUnionQuery>())
ast = std::move(select_union->list_of_selects->children.at(0));
query = serializeAST(*ast); query = serializeAST(*ast);
/// Check the limits. /// Check the limits.

View File

@ -111,6 +111,7 @@ SRCS(
MetricLog.cpp MetricLog.cpp
MutationsInterpreter.cpp MutationsInterpreter.cpp
MySQL/InterpretersMySQLDDLQuery.cpp MySQL/InterpretersMySQLDDLQuery.cpp
NormalizeSelectWithUnionQueryVisitor.cpp
NullableUtils.cpp NullableUtils.cpp
OpenTelemetrySpanLog.cpp OpenTelemetrySpanLog.cpp
OptimizeIfChains.cpp OptimizeIfChains.cpp

View File

@ -0,0 +1,66 @@
SELECT 1
UNION ALL
SELECT 1
UNION ALL
SELECT 1
UNION ALL
SELECT 1
UNION ALL
SELECT 1
SELECT 1
UNION ALL
(
SELECT 1
UNION DISTINCT
SELECT 1
UNION DISTINCT
SELECT 1
)
UNION ALL
SELECT 1
SELECT x
FROM
(
SELECT 1 AS x
UNION ALL
(
SELECT 1
UNION DISTINCT
SELECT 1
UNION DISTINCT
SELECT 1
)
UNION ALL
SELECT 1
)
SELECT x
FROM
(
SELECT 1 AS x
UNION ALL
SELECT 1
UNION ALL
SELECT 1
)
SELECT 1
UNION DISTINCT
SELECT 1
UNION DISTINCT
SELECT 1
SELECT 1
(
SELECT 1
UNION DISTINCT
SELECT 1
UNION DISTINCT
SELECT 1
)
UNION ALL
SELECT 1

View File

@ -0,0 +1,86 @@
EXPLAIN SYNTAX
SELECT 1
UNION ALL
(
SELECT 1
UNION ALL
(
SELECT 1
UNION ALL
SELECT 1
)
UNION ALL
SELECT 1
);
SELECT ' ';
EXPLAIN SYNTAX
SELECT 1
UNION ALL
(
SELECT 1
UNION DISTINCT
(
SELECT 1
UNION ALL
SELECT 1
)
UNION ALL
SELECT 1
);
SELECT ' ';
EXPLAIN SYNTAX
SELECT x
FROM
(
SELECT 1 AS x
UNION ALL
(
SELECT 1
UNION DISTINCT
(
SELECT 1
UNION ALL
SELECT 1
)
UNION ALL
SELECT 1
)
);
SELECT ' ';
EXPLAIN SYNTAX
SELECT x
FROM
(
SELECT 1 AS x
UNION ALL
(
SELECT 1
UNION ALL
SELECT 1
)
);
SELECT ' ';
EXPLAIN SYNTAX
SELECT 1
UNION ALL
SELECT 1
UNION DISTINCT
SELECT 1;
SELECT ' ';
EXPLAIN SYNTAX
(((((((((((((((SELECT 1)))))))))))))));
SELECT ' ';
EXPLAIN SYNTAX
(((((((((((((((SELECT 1 UNION DISTINCT SELECT 1))) UNION DISTINCT SELECT 1)))) UNION ALL SELECT 1))))))));