Avoid duplicating names for new inputs of ActionsDAG::split result.

This commit is contained in:
Nikolai Kochetov 2024-06-05 15:50:27 +00:00
parent 2f45caca28
commit ee5100171e
3 changed files with 41 additions and 2 deletions

View File

@ -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);
}

View File

@ -0,0 +1,2 @@
a b
a b

View File

@ -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;