mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-23 18:20:50 +00:00
dbms: Server: rewrite expression lists in each SELECT query of the UNION ALL chain, if needed. [#METR-14099]
This commit is contained in:
parent
a362a666eb
commit
282e6f3a5b
@ -79,6 +79,12 @@ private:
|
||||
/// Выполнить один запрос SELECT из цепочки UNION ALL.
|
||||
void executeSingleQuery(bool should_perform_union_hint = true);
|
||||
|
||||
/** Оставить в каждом запросе цепочки UNION ALL только нужные столбцы секции SELECT.
|
||||
* Однако, если используется хоть один DISTINCT в цепочке, то все столбцы считаются нужными,
|
||||
* так как иначе DISTINCT работал бы по-другому.
|
||||
*/
|
||||
void rewriteExpressionList(const Names & required_column_names);
|
||||
|
||||
/// Является ли это первым запросом цепочки UNION ALL имеющей длниу >= 2.
|
||||
bool isFirstSelectInsideUnionAll() const;
|
||||
|
||||
|
@ -88,9 +88,9 @@ void InterpreterSelectQuery::init(BlockInputStreamPtr input_, const NamesAndType
|
||||
|
||||
if (isFirstSelectInsideUnionAll())
|
||||
{
|
||||
// Создаем цепочку запросов SELECT и проверяем, что результаты всех запросов SELECT cовместимые.
|
||||
// NOTE Мы можем безопасно применить static_cast вместо typeid_cast,
|
||||
// потому что знаем, что в цепочке UNION ALL имеются только деревья типа SELECT.
|
||||
/// Создаем цепочку запросов SELECT и проверяем, что результаты всех запросов SELECT cовместимые.
|
||||
/// NOTE Мы можем безопасно применить static_cast вместо typeid_cast,
|
||||
/// потому что знаем, что в цепочке UNION ALL имеются только деревья типа SELECT.
|
||||
InterpreterSelectQuery * interpreter = this;
|
||||
Block first = interpreter->getSampleBlock();
|
||||
for (ASTPtr tree = query.next_union_all; !tree.isNull(); tree = (static_cast<ASTSelectQuery &>(*tree)).next_union_all)
|
||||
@ -123,12 +123,7 @@ InterpreterSelectQuery::InterpreterSelectQuery(ASTPtr query_ptr_, const Context
|
||||
is_union_all_head(true),
|
||||
log(&Logger::get("InterpreterSelectQuery"))
|
||||
{
|
||||
/** Оставляем в запросе в секции SELECT только нужные столбцы.
|
||||
* Но если используется DISTINCT, то все столбцы считаются нужными, так как иначе DISTINCT работал бы по-другому.
|
||||
*/
|
||||
if (!query.distinct)
|
||||
query.rewriteSelectExpressionList(required_column_names_);
|
||||
|
||||
rewriteExpressionList(required_column_names_);
|
||||
init(input_);
|
||||
}
|
||||
|
||||
@ -140,15 +135,31 @@ InterpreterSelectQuery::InterpreterSelectQuery(ASTPtr query_ptr_, const Context
|
||||
is_union_all_head(true),
|
||||
log(&Logger::get("InterpreterSelectQuery"))
|
||||
{
|
||||
/** Оставляем в запросе в секции SELECT только нужные столбцы.
|
||||
* Но если используется DISTINCT, то все столбцы считаются нужными, так как иначе DISTINCT работал бы по-другому.
|
||||
*/
|
||||
if (!query.distinct)
|
||||
query.rewriteSelectExpressionList(required_column_names_);
|
||||
|
||||
rewriteExpressionList(required_column_names_);
|
||||
init(input_, table_column_names);
|
||||
}
|
||||
|
||||
void InterpreterSelectQuery::rewriteExpressionList(const Names & required_column_names)
|
||||
{
|
||||
if (query.distinct)
|
||||
return;
|
||||
|
||||
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));
|
||||
if (next_query.distinct)
|
||||
return;
|
||||
}
|
||||
|
||||
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));
|
||||
next_query.rewriteSelectExpressionList(required_column_names);
|
||||
}
|
||||
}
|
||||
|
||||
bool InterpreterSelectQuery::isFirstSelectInsideUnionAll() const
|
||||
{
|
||||
return is_union_all_head && !query.next_union_all.isNull();
|
||||
|
@ -0,0 +1,2 @@
|
||||
1
|
||||
2
|
1
dbms/tests/queries/0_stateless/00098_7_union_all.sql
Normal file
1
dbms/tests/queries/0_stateless/00098_7_union_all.sql
Normal file
@ -0,0 +1 @@
|
||||
SELECT DomainID FROM (SELECT 1 AS DomainID, 'abc' AS Domain UNION ALL SELECT 2 AS DomainID, 'def' AS Domain) ORDER BY DomainID ASC
|
@ -0,0 +1,2 @@
|
||||
1
|
||||
2
|
1
dbms/tests/queries/0_stateless/00098_8_union_all.sql
Normal file
1
dbms/tests/queries/0_stateless/00098_8_union_all.sql
Normal file
@ -0,0 +1 @@
|
||||
SELECT DomainID FROM (SELECT DISTINCT 1 AS DomainID, 'abc' AS Domain UNION ALL SELECT 2 AS DomainID, 'def' AS Domain) ORDER BY DomainID ASC
|
Loading…
Reference in New Issue
Block a user