mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Fixed error with duplicate columns in subqueries [#METR-22381].
This commit is contained in:
parent
2c16a4ad2a
commit
902c70bfa9
@ -160,10 +160,24 @@ FunctionPtr getFunctionFromFactory(const String & name, const ASTFunction::Genus
|
||||
return function;
|
||||
}
|
||||
|
||||
void removeDuplicateColumns(NamesAndTypesList & columns)
|
||||
{
|
||||
std::set<String> names;
|
||||
for (auto it = columns.begin(); it != columns.end();)
|
||||
{
|
||||
if (names.emplace(it->name).second)
|
||||
++it;
|
||||
else
|
||||
columns.erase(it++);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ExpressionAnalyzer::init()
|
||||
{
|
||||
removeDuplicateColumns(columns);
|
||||
|
||||
select_query = typeid_cast<ASTSelectQuery *>(ast.get());
|
||||
|
||||
/// В зависимости от профиля пользователя проверить наличие прав на выполнение
|
||||
|
@ -66,7 +66,7 @@ void ASTSelectQuery::renameColumns(const ASTSelectQuery & source)
|
||||
}
|
||||
}
|
||||
|
||||
void ASTSelectQuery::rewriteSelectExpressionList(const Names & column_names)
|
||||
void ASTSelectQuery::rewriteSelectExpressionList(const Names & required_column_names)
|
||||
{
|
||||
ASTPtr result = std::make_shared<ASTExpressionList>();
|
||||
ASTs asts = select_expression_list->children;
|
||||
@ -91,7 +91,7 @@ void ASTSelectQuery::rewriteSelectExpressionList(const Names & column_names)
|
||||
Mapping mapping(asts.size());
|
||||
|
||||
/// На какой позиции в SELECT-выражении находится соответствующий столбец из column_names.
|
||||
std::vector<size_t> from(column_names.size());
|
||||
std::vector<size_t> positions_of_required_columns(required_column_names.size());
|
||||
|
||||
/// Не будем выбрасывать выражения, содержащие функцию arrayJoin.
|
||||
for (size_t i = 0; i < asts.size(); ++i)
|
||||
@ -100,31 +100,29 @@ void ASTSelectQuery::rewriteSelectExpressionList(const Names & column_names)
|
||||
mapping[i] = Arrow(i);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < column_names.size(); ++i)
|
||||
for (size_t i = 0; i < required_column_names.size(); ++i)
|
||||
{
|
||||
bool done = false;
|
||||
for (size_t j = 0; j < asts.size(); ++j)
|
||||
size_t j = 0;
|
||||
for (; j < asts.size(); ++j)
|
||||
{
|
||||
if (asts[j]->getAliasOrColumnName() == column_names[i])
|
||||
if (asts[j]->getAliasOrColumnName() == required_column_names[i])
|
||||
{
|
||||
from[i] = j;
|
||||
done = true;
|
||||
positions_of_required_columns[i] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!done)
|
||||
if (j == asts.size())
|
||||
throw Exception("Error while rewriting expression list for select query."
|
||||
" Could not find alias: " + column_names[i],
|
||||
" Could not find alias: " + required_column_names[i],
|
||||
DB::ErrorCodes::UNKNOWN_IDENTIFIER);
|
||||
}
|
||||
|
||||
auto to = from;
|
||||
std::vector<size_t> positions_of_required_columns_in_subquery_order = positions_of_required_columns;
|
||||
std::sort(positions_of_required_columns_in_subquery_order.begin(), positions_of_required_columns_in_subquery_order.end());
|
||||
|
||||
/// Теперь from - список позиций column_names по возрастанию.
|
||||
std::sort(from.begin(), from.end());
|
||||
for (size_t i = 0; i < required_column_names.size(); ++i)
|
||||
mapping[positions_of_required_columns_in_subquery_order[i]] = Arrow(positions_of_required_columns[i]);
|
||||
|
||||
for (size_t i = 0; i < column_names.size(); ++i)
|
||||
mapping[from[i]] = Arrow(to[i]);
|
||||
|
||||
/// Составить новое выражение.
|
||||
for (const auto & arrow : mapping)
|
||||
|
@ -0,0 +1,12 @@
|
||||
1 2
|
||||
1 1
|
||||
1
|
||||
1 2
|
||||
1 1 1
|
||||
1 1
|
||||
1 1
|
||||
1 1
|
||||
42 1 2
|
||||
42 1 2
|
||||
0 hello world
|
||||
1 hello world
|
@ -0,0 +1,12 @@
|
||||
select x, y from (select 1 as x, 2 as y, x, y);
|
||||
select x, y from (select 1 as x, 1 as y, x, y);
|
||||
select x from (select 1 as x, 1 as y, x, y);
|
||||
select * from (select 1 as x, 2 as y, x, y);
|
||||
select * from (select 1 as a, 1 as b, 1 as c, b, c);
|
||||
select b, c from (select 1 as a, 1 as b, 1 as c, b, c);
|
||||
select b, c from (select 1 as a, 1 as b, 1 as c, b, c) any left join (select 1 as a) using a;
|
||||
select b, c from (select 1 as a, 1 as b, 1 as c, 1 as b, 1 as c) any left join (select 1 as a) using a;
|
||||
select a, b, c from (select 42 as a, 1 as b, 2 as c, 1 as b, 2 as c) any left join (select 42 as a, 3 as d) using a;
|
||||
select a, b, c from (select 42 as a, 1 as b, 2 as c, 1 as b, 2 as c) any left join (select 42 as a, 3 as d) using a order by d;
|
||||
|
||||
SELECT k, a1, b1, a2, b2 FROM (SELECT 0 AS k, 'hello' AS a1, 'world' AS b1, a1) ANY FULL OUTER JOIN (SELECT 1 AS k, 'hello' AS a2, 'world' AS b2, a2) USING (k) ORDER BY k;
|
Loading…
Reference in New Issue
Block a user