mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
dbms: Server: second part of the fix for column renaming in UNION ALL queries. [#METR-14099]
This commit is contained in:
parent
ece876f05d
commit
9c9db14d95
@ -266,6 +266,7 @@ namespace ErrorCodes
|
|||||||
PARTITION_ALREADY_EXISTS,
|
PARTITION_ALREADY_EXISTS,
|
||||||
PARTITION_DOESNT_EXIST,
|
PARTITION_DOESNT_EXIST,
|
||||||
UNION_ALL_RESULT_STRUCTURES_MISMATCH,
|
UNION_ALL_RESULT_STRUCTURES_MISMATCH,
|
||||||
|
UNION_ALL_COLUMN_ALIAS_MISMATCH,
|
||||||
CLIENT_OUTPUT_FORMAT_SPECIFIED,
|
CLIENT_OUTPUT_FORMAT_SPECIFIED,
|
||||||
|
|
||||||
POCO_EXCEPTION = 1000,
|
POCO_EXCEPTION = 1000,
|
||||||
|
@ -55,16 +55,23 @@ public:
|
|||||||
/// Переименовать столбцы в такие же имена, как в source.
|
/// Переименовать столбцы в такие же имена, как в source.
|
||||||
void renameColumns(const ASTSelectQuery & source)
|
void renameColumns(const ASTSelectQuery & source)
|
||||||
{
|
{
|
||||||
ASTs & to = select_expression_list->children;
|
|
||||||
const ASTs & from = source.select_expression_list->children;
|
const ASTs & from = source.select_expression_list->children;
|
||||||
|
ASTs & to = select_expression_list->children;
|
||||||
|
|
||||||
if (from.size() != to.size())
|
if (from.size() != to.size())
|
||||||
/// XXX Временно!!! Скоро придумаем собственные сообщение + исключение.
|
throw Exception("Size mismatch in UNION ALL chain",
|
||||||
throw Exception("FATAL ERROR", DB::ErrorCodes::UNKNOWN_IDENTIFIER);
|
DB::ErrorCodes::UNION_ALL_RESULT_STRUCTURES_MISMATCH);
|
||||||
|
|
||||||
for (size_t i = 0; i < from.size(); ++i)
|
for (size_t i = 0; i < from.size(); ++i)
|
||||||
{
|
{
|
||||||
if (from[i]->getAliasOrColumnName() != to[i]->getAliasOrColumnName())
|
const auto & from_alias = from[i]->tryGetAlias();
|
||||||
|
const auto & to_alias = to[i]->tryGetAlias();
|
||||||
|
if (!to_alias.empty() && !from_alias.empty())
|
||||||
|
if (to_alias != from_alias)
|
||||||
|
throw Exception("Column alias mismatch in UNION ALL chain",
|
||||||
|
DB::ErrorCodes::UNION_ALL_COLUMN_ALIAS_MISMATCH);
|
||||||
|
|
||||||
|
if (to[i]->getAliasOrColumnName() != from[i]->getAliasOrColumnName())
|
||||||
to[i]->setAlias(from[i]->getAliasOrColumnName());
|
to[i]->setAlias(from[i]->getAliasOrColumnName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,9 +105,9 @@ void InterpreterSelectQuery::init(BlockInputStreamPtr input_, const NamesAndType
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Переименовать столбцы каждого запроса цепочки UNION ALL в такие же имена, как в первом запросе.
|
// Переименовать столбцы каждого запроса цепочки UNION ALL в такие же имена, как в первом запросе.
|
||||||
for (ASTPtr tree = query.next_union_all; !tree.isNull(); tree = (static_cast<ASTSelectQuery &>(*tree)).next_union_all)
|
for (IAST * tree = query.next_union_all.get(); tree != nullptr; tree = static_cast<ASTSelectQuery *>(tree)->next_union_all.get())
|
||||||
{
|
{
|
||||||
ASTSelectQuery & ast = static_cast<ASTSelectQuery &>(*(tree.get()));
|
auto & ast = static_cast<ASTSelectQuery &>(*tree);
|
||||||
ast.renameColumns(query);
|
ast.renameColumns(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,13 +115,12 @@ void InterpreterSelectQuery::init(BlockInputStreamPtr input_, const NamesAndType
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// XXX Временный boilerplate код, который сотру очень скоро. Не обращать внимание.
|
/// XXX Временный boilerplate код, который сотру очень скоро. Не обращать внимание.
|
||||||
/// на него. Дело в том, что rewriteExpressionList() может не работать правильно,
|
/// на него. Дело в том, что функция rewriteExpressionList() может работать неправильно,
|
||||||
/// если мы не вызываем renameColumns() перед ним. В свою очередь renameColumns()
|
/// если мы не вызываем renameColumns() до нее. В свою очередь renameColumns()
|
||||||
/// будет работать правильно лишь в том случае, если обладает достаточно информаций,
|
/// будет работать правильно лишь в том случае, если обладает достаточно информаций,
|
||||||
/// то, что возможно только после построения объекта query_analyzer.
|
/// то, что возможно только после создания объекта query_analyzer.
|
||||||
/// Но тогда, после вызова rewriteExpressionList(), InterpreterSelectQuery содержит
|
/// Но тогда, после вызова rewriteExpressionList(), объект InterpreterSelectQuery хранит
|
||||||
/// неправильнии информации. Единственный выход - заново инициализировать объект
|
/// неправильные информации. Единственный выход - заново инициализировать этот объект.
|
||||||
/// InterpreterSelectQuery.
|
|
||||||
///
|
///
|
||||||
void InterpreterSelectQuery::reinit(const NamesAndTypesList & table_column_names)
|
void InterpreterSelectQuery::reinit(const NamesAndTypesList & table_column_names)
|
||||||
{
|
{
|
||||||
@ -215,7 +214,7 @@ void InterpreterSelectQuery::rewriteExpressionList(const Names & required_column
|
|||||||
|
|
||||||
for (IAST* tree = query.next_union_all.get(); tree != nullptr; tree = static_cast<ASTSelectQuery *>(tree)->next_union_all.get())
|
for (IAST* tree = query.next_union_all.get(); tree != nullptr; tree = static_cast<ASTSelectQuery *>(tree)->next_union_all.get())
|
||||||
{
|
{
|
||||||
auto & next_query = *(static_cast<ASTSelectQuery *>(tree));
|
auto & next_query = static_cast<ASTSelectQuery &>(*tree);
|
||||||
if (next_query.distinct)
|
if (next_query.distinct)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -223,7 +222,7 @@ void InterpreterSelectQuery::rewriteExpressionList(const Names & required_column
|
|||||||
query.rewriteSelectExpressionList(required_column_names);
|
query.rewriteSelectExpressionList(required_column_names);
|
||||||
for (IAST* tree = query.next_union_all.get(); tree != nullptr; tree = static_cast<ASTSelectQuery *>(tree)->next_union_all.get())
|
for (IAST* tree = query.next_union_all.get(); tree != nullptr; tree = static_cast<ASTSelectQuery *>(tree)->next_union_all.get())
|
||||||
{
|
{
|
||||||
auto & next_query = *(static_cast<ASTSelectQuery *>(tree));
|
auto & next_query = static_cast<ASTSelectQuery &>(*tree);
|
||||||
next_query.rewriteSelectExpressionList(required_column_names);
|
next_query.rewriteSelectExpressionList(required_column_names);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
1
|
||||||
|
2
|
1
dbms/tests/queries/0_stateless/00098_9_union_all.sql
Normal file
1
dbms/tests/queries/0_stateless/00098_9_union_all.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
SELECT * FROM (SELECT 1 UNION ALL SELECT 2 AS X) ORDER BY 1 ASC;
|
@ -0,0 +1,2 @@
|
|||||||
|
1
|
||||||
|
2
|
1
dbms/tests/queries/0_stateless/00098_a_union_all.sql
Normal file
1
dbms/tests/queries/0_stateless/00098_a_union_all.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
SELECT * FROM (SELECT 1 AS X UNION ALL SELECT 2) ORDER BY X ASC;
|
@ -0,0 +1,3 @@
|
|||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
1
dbms/tests/queries/0_stateless/00098_b_union_all.sql
Normal file
1
dbms/tests/queries/0_stateless/00098_b_union_all.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
SELECT * FROM (SELECT 1 UNION ALL SELECT 2 AS X UNION ALL SELECT 3 AS Y) ORDER BY 1 ASC;
|
11
dbms/tests/queries/0_stateless/00098_c_union_all.reference
Normal file
11
dbms/tests/queries/0_stateless/00098_c_union_all.reference
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
8
|
||||||
|
9
|
||||||
|
10
|
||||||
|
12345678902
|
1
dbms/tests/queries/0_stateless/00098_c_union_all.sql
Normal file
1
dbms/tests/queries/0_stateless/00098_c_union_all.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
SELECT X + 1 FROM (SELECT 12345678901 AS X UNION ALL SELECT number FROM system.numbers LIMIT 10) ORDER BY X ASC;
|
Loading…
Reference in New Issue
Block a user