Merge pull request #60102 from ClickHouse/fix-inconsistent-formatting-of-explain-in-subqueries

Fix inconsistent formatting of explain in subqueries
This commit is contained in:
Alexey Milovidov 2024-02-19 01:35:57 +01:00 committed by GitHub
commit f469fd084f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 59 additions and 34 deletions

View File

@ -421,11 +421,8 @@ ASTPtr QueryNode::toASTImpl(const ConvertToASTOptions & options) const
if (is_subquery)
{
auto subquery = std::make_shared<ASTSubquery>();
auto subquery = std::make_shared<ASTSubquery>(std::move(result_select_query));
subquery->cte_name = cte_name;
subquery->children.push_back(std::move(result_select_query));
return subquery;
}

View File

@ -185,11 +185,8 @@ ASTPtr UnionNode::toASTImpl(const ConvertToASTOptions & options) const
if (is_subquery)
{
auto subquery = std::make_shared<ASTSubquery>();
auto subquery = std::make_shared<ASTSubquery>(std::move(select_with_union_query));
subquery->cte_name = cte_name;
subquery->children.push_back(std::move(select_with_union_query));
return subquery;
}

View File

@ -262,8 +262,7 @@ struct ExistsExpressionData
select_with_union_query->list_of_selects->children.push_back(std::move(select_query));
select_with_union_query->children.push_back(select_with_union_query->list_of_selects);
auto new_subquery = std::make_shared<ASTSubquery>();
new_subquery->children.push_back(select_with_union_query);
auto new_subquery = std::make_shared<ASTSubquery>(std::move(select_with_union_query));
auto function = makeASTFunction("in", std::make_shared<ASTLiteral>(1u), new_subquery);
func = *function;

View File

@ -71,8 +71,7 @@ void ASTSelectWithUnionQuery::formatQueryImpl(const FormatSettings & settings, F
}
else
{
auto sub_query = std::make_shared<ASTSubquery>();
sub_query->children.push_back(*it);
auto sub_query = std::make_shared<ASTSubquery>(*it);
sub_query->formatImpl(settings, state, frame);
}
}

View File

@ -26,6 +26,13 @@ public:
return clone;
}
ASTSubquery() = default;
ASTSubquery(ASTPtr child)
{
children.emplace_back(std::move(child));
}
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
String getAliasOrColumnName() const override;
String tryGetAlias() const override;

View File

@ -123,7 +123,7 @@ bool ParserSubquery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
throw Exception(ErrorCodes::BAD_ARGUMENTS, "EXPLAIN in a subquery cannot have a table function or table override");
/// Replace subquery `(EXPLAIN <kind> <explain_settings> SELECT ...)`
/// with `(SELECT * FROM viewExplain("<kind>", "<explain_settings>", SELECT ...))`
/// with `(SELECT * FROM viewExplain('<kind>', '<explain_settings>', (SELECT ...)))`
String kind_str = ASTExplainQuery::toString(explain_query.getKind());
@ -141,7 +141,7 @@ bool ParserSubquery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
auto view_explain = makeASTFunction("viewExplain",
std::make_shared<ASTLiteral>(kind_str),
std::make_shared<ASTLiteral>(settings_str),
explained_ast);
std::make_shared<ASTSubquery>(explained_ast));
result_node = buildSelectFromTableFunction(view_explain);
}
else
@ -161,8 +161,7 @@ bool ParserSubquery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
return false;
++pos;
node = std::make_shared<ASTSubquery>();
node->children.push_back(result_node);
node = std::make_shared<ASTSubquery>(std::move(result_node));
return true;
}

View File

@ -225,8 +225,7 @@ static bool modifyAST(ASTPtr ast, SubqueryFunctionType type)
select_with_union_query->list_of_selects->children.push_back(std::move(select_query));
select_with_union_query->children.push_back(select_with_union_query->list_of_selects);
auto new_subquery = std::make_shared<ASTSubquery>();
new_subquery->children.push_back(select_with_union_query);
auto new_subquery = std::make_shared<ASTSubquery>(std::move(select_with_union_query));
ast->children[0]->children.back() = std::move(new_subquery);
return true;
@ -1582,8 +1581,7 @@ public:
if (!ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
return false;
auto subquery = std::make_shared<ASTSubquery>();
subquery->children.push_back(std::move(node));
auto subquery = std::make_shared<ASTSubquery>(std::move(node));
elements = {makeASTFunction("exists", subquery)};
finished = true;

View File

@ -576,20 +576,19 @@ bool ParserKQLSubquery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
if (!ParserKQLTableFunction().parse(pos, select_node, expected))
return false;
ASTPtr node_subquery = std::make_shared<ASTSubquery>();
node_subquery->children.push_back(select_node);
ASTPtr node_subquery = std::make_shared<ASTSubquery>(std::move(select_node));
ASTPtr node_table_expr = std::make_shared<ASTTableExpression>();
node_table_expr->as<ASTTableExpression>()->subquery = node_subquery;
node_table_expr->children.emplace_back(node_subquery);
ASTPtr node_table_in_select_query_emlement = std::make_shared<ASTTablesInSelectQueryElement>();
node_table_in_select_query_emlement->as<ASTTablesInSelectQueryElement>()->table_expression = node_table_expr;
ASTPtr node_table_in_select_query_element = std::make_shared<ASTTablesInSelectQueryElement>();
node_table_in_select_query_element->as<ASTTablesInSelectQueryElement>()->table_expression = node_table_expr;
ASTPtr res = std::make_shared<ASTTablesInSelectQuery>();
res->children.emplace_back(node_table_in_select_query_emlement);
res->children.emplace_back(node_table_in_select_query_element);
node = res;
return true;
@ -618,20 +617,19 @@ bool ParserSimpleCHSubquery::parseImpl(Pos & pos, ASTPtr & node, Expected & expe
ASTSelectQuery::Expression::TABLES, parent_select_node->as<ASTSelectQuery>()->tables());
}
ASTPtr node_subquery = std::make_shared<ASTSubquery>();
node_subquery->children.push_back(sub_select_node);
ASTPtr node_subquery = std::make_shared<ASTSubquery>(std::move(sub_select_node));
ASTPtr node_table_expr = std::make_shared<ASTTableExpression>();
node_table_expr->as<ASTTableExpression>()->subquery = node_subquery;
node_table_expr->children.emplace_back(node_subquery);
ASTPtr node_table_in_select_query_emlement = std::make_shared<ASTTablesInSelectQueryElement>();
node_table_in_select_query_emlement->as<ASTTablesInSelectQueryElement>()->table_expression = node_table_expr;
ASTPtr node_table_in_select_query_element = std::make_shared<ASTTablesInSelectQueryElement>();
node_table_in_select_query_element->as<ASTTablesInSelectQueryElement>()->table_expression = node_table_expr;
ASTPtr res = std::make_shared<ASTTablesInSelectQuery>();
res->children.emplace_back(node_table_in_select_query_emlement);
res->children.emplace_back(node_table_in_select_query_element);
node = res;
return true;

View File

@ -251,8 +251,7 @@ void StorageView::replaceWithSubquery(ASTSelectQuery & outer_query, ASTPtr view_
view_name = table_expression->database_and_table_name;
table_expression->database_and_table_name = {};
table_expression->subquery = std::make_shared<ASTSubquery>();
table_expression->subquery->children.push_back(view_query);
table_expression->subquery = std::make_shared<ASTSubquery>(view_query);
table_expression->subquery->setAlias(alias);
for (auto & child : table_expression->children)

View File

@ -1,4 +1,5 @@
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTSubquery.h>
#include <Parsers/ASTSelectWithUnionQuery.h>
#include <Parsers/ParserSetQuery.h>
#include <Parsers/parseQuery.h>
@ -21,6 +22,7 @@ namespace ErrorCodes
{
extern const int LOGICAL_ERROR;
extern const int BAD_ARGUMENTS;
extern const int UNEXPECTED_AST_STRUCTURE;
}
namespace
@ -103,11 +105,25 @@ void TableFunctionExplain::parseArguments(const ASTPtr & ast_function, ContextPt
if (function->arguments->children.size() > 2)
{
const auto & query_arg = function->arguments->children[2];
const auto & subquery_arg = function->arguments->children[2];
const auto * subquery = subquery_arg->as<ASTSubquery>();
if (!subquery)
throw Exception(ErrorCodes::BAD_ARGUMENTS,
"Table function '{}' requires a subquery argument, got '{}'",
getName(), queryToString(subquery_arg));
if (subquery->children.empty())
throw Exception(ErrorCodes::UNEXPECTED_AST_STRUCTURE,
"A subquery AST element must have a child");
const auto & query_arg = subquery->children[0];
if (!query_arg->as<ASTSelectWithUnionQuery>())
throw Exception(ErrorCodes::BAD_ARGUMENTS,
"Table function '{}' requires a EXPLAIN SELECT query argument, got EXPLAIN '{}'",
"Table function '{}' requires a EXPLAIN's SELECT query argument, got '{}'",
getName(), queryToString(query_arg));
explain_query->setExplainedQuery(query_arg);
}
else if (kind != ASTExplainQuery::ExplainKind::CurrentTransaction)

View File

@ -0,0 +1,9 @@
SELECT explain
FROM
(
SELECT *
FROM viewExplain('EXPLAIN AST', '', (
SELECT *
FROM system.numbers
))
)

View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=../shell_config.sh
. "$CURDIR"/../shell_config.sh
${CLICKHOUSE_FORMAT} --query "SELECT explain FROM (EXPLAIN AST SELECT * FROM system.numbers)"