mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-25 09:02:00 +00:00
Fix global with after union refactoring
This commit is contained in:
parent
824aee4020
commit
3afcccaad2
@ -404,7 +404,7 @@ class IColumn;
|
||||
M(MySQLDataTypesSupport, mysql_datatypes_support_level, 0, "Which MySQL types should be converted to corresponding ClickHouse types (rather than being represented as String). Can be empty or any combination of 'decimal' or 'datetime64'. When empty MySQL's DECIMAL and DATETIME/TIMESTAMP with non-zero precision are seen as String on ClickHouse's side.", 0) \
|
||||
M(Bool, optimize_trivial_insert_select, true, "Optimize trivial 'INSERT INTO table SELECT ... FROM TABLES' query", 0) \
|
||||
M(Bool, allow_non_metadata_alters, true, "Allow to execute alters which affects not only tables metadata, but also data on disk", 0) \
|
||||
M(Bool, enable_global_with_statement, false, "Propagate WITH statements to UNION queries and all subqueries", 0) \
|
||||
M(Bool, enable_global_with_statement, true, "Propagate WITH statements to UNION queries and all subqueries", 0) \
|
||||
M(Bool, aggregate_functions_null_for_empty, false, "Rewrite all aggregate functions in a query, adding -OrNull suffix to them", 0) \
|
||||
M(Bool, flatten_nested, true, "If true, columns of type Nested will be flatten to separate array columns instead of one array of tuples", 0) \
|
||||
M(Bool, asterisk_include_materialized_columns, false, "Include MATERIALIZED columns for wildcard query", 0) \
|
||||
|
@ -3,51 +3,71 @@
|
||||
#include <Parsers/ASTSelectWithUnionQuery.h>
|
||||
#include <Parsers/ASTWithAlias.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void ApplyWithGlobalVisitor::visit(ASTSelectQuery & select, const std::map<String, ASTPtr> & exprs, const ASTPtr & with_expression_list)
|
||||
{
|
||||
auto with = select.with();
|
||||
if (with)
|
||||
{
|
||||
std::set<String> current_names;
|
||||
for (auto & child : with->children)
|
||||
{
|
||||
if (auto * ast_with_alias = dynamic_cast<ASTWithAlias *>(child.get()))
|
||||
current_names.insert(ast_with_alias->alias);
|
||||
}
|
||||
for (auto & with_alias : exprs)
|
||||
{
|
||||
if (!current_names.count(with_alias.first))
|
||||
with->children.push_back(with_alias.second->clone());
|
||||
}
|
||||
}
|
||||
else
|
||||
select.setExpression(ASTSelectQuery::Expression::WITH, with_expression_list->clone());
|
||||
}
|
||||
|
||||
void ApplyWithGlobalVisitor::visit(
|
||||
ASTSelectWithUnionQuery & selects, const std::map<String, ASTPtr> & exprs, const ASTPtr & with_expression_list)
|
||||
{
|
||||
for (auto & select : selects.list_of_selects->children)
|
||||
{
|
||||
if (ASTSelectWithUnionQuery * node_union = select->as<ASTSelectWithUnionQuery>())
|
||||
{
|
||||
visit(*node_union, exprs, with_expression_list);
|
||||
}
|
||||
else if (ASTSelectQuery * node_select = select->as<ASTSelectQuery>())
|
||||
{
|
||||
visit(*node_select, exprs, with_expression_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyWithGlobalVisitor::visit(ASTPtr & ast)
|
||||
{
|
||||
if (ASTSelectWithUnionQuery * node_union = ast->as<ASTSelectWithUnionQuery>())
|
||||
{
|
||||
auto & first_select = node_union->list_of_selects->children[0]->as<ASTSelectQuery &>();
|
||||
ASTPtr with_expression_list = first_select.with();
|
||||
|
||||
if (with_expression_list)
|
||||
if (auto * first_select = node_union->list_of_selects->children[0]->as<ASTSelectQuery>())
|
||||
{
|
||||
std::map<String, ASTPtr> exprs;
|
||||
for (auto & child : with_expression_list->children)
|
||||
ASTPtr with_expression_list = first_select->with();
|
||||
if (with_expression_list)
|
||||
{
|
||||
if (auto * ast_with_alias = dynamic_cast<ASTWithAlias *>(child.get()))
|
||||
exprs[ast_with_alias->alias] = child;
|
||||
}
|
||||
for (auto it = node_union->list_of_selects->children.begin() + 1; it != node_union->list_of_selects->children.end(); ++it)
|
||||
{
|
||||
auto & select = (*it)->as<ASTSelectQuery &>();
|
||||
auto with = select.with();
|
||||
if (with)
|
||||
std::map<String, ASTPtr> exprs;
|
||||
for (auto & child : with_expression_list->children)
|
||||
{
|
||||
std::set<String> current_names;
|
||||
for (auto & child : with->children)
|
||||
{
|
||||
if (auto * ast_with_alias = dynamic_cast<ASTWithAlias *>(child.get()))
|
||||
current_names.insert(ast_with_alias->alias);
|
||||
}
|
||||
for (auto & with_alias : exprs)
|
||||
{
|
||||
if (!current_names.count(with_alias.first))
|
||||
with->children.push_back(with_alias.second->clone());
|
||||
}
|
||||
if (auto * ast_with_alias = dynamic_cast<ASTWithAlias *>(child.get()))
|
||||
exprs[ast_with_alias->alias] = child;
|
||||
}
|
||||
for (auto it = node_union->list_of_selects->children.begin() + 1; it != node_union->list_of_selects->children.end(); ++it)
|
||||
{
|
||||
if (auto * union_child = (*it)->as<ASTSelectWithUnionQuery>())
|
||||
visit(*union_child, exprs, with_expression_list);
|
||||
else if (auto * select_child = (*it)->as<ASTSelectQuery>())
|
||||
visit(*select_child, exprs, with_expression_list);
|
||||
}
|
||||
else
|
||||
select.setExpression(ASTSelectQuery::Expression::WITH, with_expression_list->clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto & child : ast->children)
|
||||
visit(child);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,14 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <Parsers/IAST.h>
|
||||
#include <map>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
class ASTSelectWithUnionQuery;
|
||||
class ASTSelectQuery;
|
||||
|
||||
/// Pull out the WITH statement from the first child of ASTSelectWithUnion query if any.
|
||||
class ApplyWithGlobalVisitor
|
||||
{
|
||||
public:
|
||||
static void visit(ASTPtr & ast);
|
||||
|
||||
private:
|
||||
static void visit(ASTSelectWithUnionQuery & selects, const std::map<String, ASTPtr> & exprs, const ASTPtr & with_expression_list);
|
||||
static void visit(ASTSelectQuery & select, const std::map<String, ASTPtr> & exprs, const ASTPtr & with_expression_list);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
SET union_default_mode = 'DISTINCT';
|
||||
|
||||
set enable_global_with_statement = 1;
|
||||
|
||||
EXPLAIN SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1;
|
||||
EXPLAIN (SELECT 1 UNION ALL SELECT 1) UNION ALL SELECT 1;
|
||||
EXPLAIN SELECT 1 UNION (SELECT 1 UNION ALL SELECT 1);
|
||||
|
Loading…
Reference in New Issue
Block a user