mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 01:25:21 +00:00
Avoid duplicating names for new inputs of ActionsDAG::split result.
This commit is contained in:
parent
2f45caca28
commit
ee5100171e
@ -1718,6 +1718,13 @@ ActionsDAG::SplitResult ActionsDAG::split(std::unordered_set<const Node *> split
|
||||
/// List of nodes from current actions which are not inputs, but will be in second part.
|
||||
NodeRawConstPtrs new_inputs;
|
||||
|
||||
/// Avoid new inputs to have the same name as existing inputs.
|
||||
/// It's allowed for DAG but may break Block invariant 'columns with identical name must have identical structure'.
|
||||
std::unordered_set<std::string_view> duplicate_inputs;
|
||||
size_t duplicate_counter = 0;
|
||||
for (const auto * input : inputs)
|
||||
duplicate_inputs.insert(input->result_name);
|
||||
|
||||
struct Frame
|
||||
{
|
||||
const Node * node = nullptr;
|
||||
@ -1830,7 +1837,8 @@ ActionsDAG::SplitResult ActionsDAG::split(std::unordered_set<const Node *> split
|
||||
input_node.result_name = child->result_name;
|
||||
child_data.to_second = &second_nodes.emplace_back(std::move(input_node));
|
||||
|
||||
new_inputs.push_back(child);
|
||||
if (child->type != ActionType::INPUT)
|
||||
new_inputs.push_back(child);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1886,7 +1894,29 @@ ActionsDAG::SplitResult ActionsDAG::split(std::unordered_set<const Node *> split
|
||||
|
||||
for (const auto * input : new_inputs)
|
||||
{
|
||||
const auto & cur = data[input];
|
||||
auto & cur = data[input];
|
||||
|
||||
bool is_name_updated = false;
|
||||
while (!duplicate_inputs.insert(cur.to_first->result_name).second)
|
||||
{
|
||||
is_name_updated = true;
|
||||
cur.to_first->result_name = fmt::format("{}_{}", input->result_name, duplicate_counter);
|
||||
++duplicate_counter;
|
||||
}
|
||||
|
||||
if (is_name_updated)
|
||||
{
|
||||
Node input_node;
|
||||
input_node.type = ActionType::INPUT;
|
||||
input_node.result_type = cur.to_first->result_type;
|
||||
input_node.result_name = cur.to_first->result_name;
|
||||
|
||||
auto * new_input = &second_nodes.emplace_back(std::move(input_node));
|
||||
cur.to_second->type = ActionType::ALIAS;
|
||||
cur.to_second->children = {new_input};
|
||||
cur.to_second = new_input;
|
||||
}
|
||||
|
||||
second_inputs.push_back(cur.to_second);
|
||||
first_outputs.push_back(cur.to_first);
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
a b
|
||||
a b
|
@ -0,0 +1,7 @@
|
||||
create table src (x Int64) engine = Log;
|
||||
create table dst (s String, lc LowCardinality(String)) engine MergeTree order by s;
|
||||
create materialized view mv to dst (s String, lc String) as select 'a' as s, toLowCardinality('b') as lc from src;
|
||||
insert into src values (1);
|
||||
|
||||
select s, lc from mv where not ignore(lc) settings allow_experimental_analyzer=0;
|
||||
select s, lc from mv where not ignore(lc) settings allow_experimental_analyzer=1;
|
Loading…
Reference in New Issue
Block a user