mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 07:01:59 +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_DOESNT_EXIST,
|
||||
UNION_ALL_RESULT_STRUCTURES_MISMATCH,
|
||||
UNION_ALL_COLUMN_ALIAS_MISMATCH,
|
||||
CLIENT_OUTPUT_FORMAT_SPECIFIED,
|
||||
|
||||
POCO_EXCEPTION = 1000,
|
||||
|
@ -55,20 +55,27 @@ public:
|
||||
/// Переименовать столбцы в такие же имена, как в source.
|
||||
void renameColumns(const ASTSelectQuery & source)
|
||||
{
|
||||
ASTs & to = select_expression_list->children;
|
||||
const ASTs & from = source.select_expression_list->children;
|
||||
|
||||
ASTs & to = select_expression_list->children;
|
||||
|
||||
if (from.size() != to.size())
|
||||
/// XXX Временно!!! Скоро придумаем собственные сообщение + исключение.
|
||||
throw Exception("FATAL ERROR", DB::ErrorCodes::UNKNOWN_IDENTIFIER);
|
||||
|
||||
throw Exception("Size mismatch in UNION ALL chain",
|
||||
DB::ErrorCodes::UNION_ALL_RESULT_STRUCTURES_MISMATCH);
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Переписывает select_expression_list, чтобы вернуть только необходимые столбцы в правильном порядке.
|
||||
void rewriteSelectExpressionList(const Names & column_names)
|
||||
{
|
||||
|
@ -103,11 +103,11 @@ void InterpreterSelectQuery::init(BlockInputStreamPtr input_, const NamesAndType
|
||||
+ "\n\nwhile expecting:\n\n" + first.dumpStructure() + "\n\ninstead",
|
||||
ErrorCodes::UNION_ALL_RESULT_STRUCTURES_MISMATCH);
|
||||
}
|
||||
|
||||
|
||||
// Переименовать столбцы каждого запроса цепочки 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);
|
||||
}
|
||||
}
|
||||
@ -115,13 +115,12 @@ void InterpreterSelectQuery::init(BlockInputStreamPtr input_, const NamesAndType
|
||||
|
||||
///
|
||||
/// XXX Временный boilerplate код, который сотру очень скоро. Не обращать внимание.
|
||||
/// на него. Дело в том, что rewriteExpressionList() может не работать правильно,
|
||||
/// если мы не вызываем renameColumns() перед ним. В свою очередь renameColumns()
|
||||
/// на него. Дело в том, что функция rewriteExpressionList() может работать неправильно,
|
||||
/// если мы не вызываем renameColumns() до нее. В свою очередь renameColumns()
|
||||
/// будет работать правильно лишь в том случае, если обладает достаточно информаций,
|
||||
/// то, что возможно только после построения объекта query_analyzer.
|
||||
/// Но тогда, после вызова rewriteExpressionList(), InterpreterSelectQuery содержит
|
||||
/// неправильнии информации. Единственный выход - заново инициализировать объект
|
||||
/// InterpreterSelectQuery.
|
||||
/// то, что возможно только после создания объекта query_analyzer.
|
||||
/// Но тогда, после вызова rewriteExpressionList(), объект InterpreterSelectQuery хранит
|
||||
/// неправильные информации. Единственный выход - заново инициализировать этот объект.
|
||||
///
|
||||
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())
|
||||
{
|
||||
auto & next_query = *(static_cast<ASTSelectQuery *>(tree));
|
||||
auto & next_query = static_cast<ASTSelectQuery &>(*tree);
|
||||
if (next_query.distinct)
|
||||
return;
|
||||
}
|
||||
@ -223,7 +222,7 @@ void InterpreterSelectQuery::rewriteExpressionList(const Names & required_column
|
||||
query.rewriteSelectExpressionList(required_column_names);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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