mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 07:01:59 +00:00
dbms: removing duplicate elements from ORDER BY [#METR-2944].
This commit is contained in:
parent
ed0bb6f3da
commit
db2956eb73
@ -218,6 +218,9 @@ private:
|
||||
/// Eliminates injective function calls and constant expressions from group by statement
|
||||
void optimizeGroupBy();
|
||||
|
||||
/// Удалить из ORDER BY повторяющиеся элементы.
|
||||
void optimizeOrderBy();
|
||||
|
||||
/// Превратить перечисление значений или подзапрос в ASTSet. node - функция in или notIn.
|
||||
void makeSet(ASTFunction * node, const Block & sample_block);
|
||||
|
||||
|
@ -85,6 +85,9 @@ void ExpressionAnalyzer::init()
|
||||
/// GROUP BY injective function elimination.
|
||||
optimizeGroupBy();
|
||||
|
||||
/// Удалить из ORDER BY повторяющиеся элементы.
|
||||
optimizeOrderBy();
|
||||
|
||||
/// array_join_alias_to_name, array_join_result_to_source.
|
||||
getArrayJoinedColumns();
|
||||
|
||||
@ -531,6 +534,38 @@ void ExpressionAnalyzer::optimizeGroupBy()
|
||||
}
|
||||
|
||||
|
||||
void ExpressionAnalyzer::optimizeOrderBy()
|
||||
{
|
||||
if (!(select_query && select_query->order_expression_list))
|
||||
return;
|
||||
|
||||
/// Уникализируем условия сортировки.
|
||||
using NameAndLocale = std::pair<std::string, std::string>;
|
||||
std::set<NameAndLocale> elems_set;
|
||||
|
||||
ASTs & elems = select_query->order_expression_list->children;
|
||||
ASTs unique_elems;
|
||||
unique_elems.reserve(elems.size());
|
||||
|
||||
for (const auto & elem : elems)
|
||||
{
|
||||
String name = elem->children.front()->getColumnName();
|
||||
const ASTOrderByElement & order_by_elem = typeid_cast<const ASTOrderByElement &>(*elem);
|
||||
|
||||
if (elems_set.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(name),
|
||||
std::forward_as_tuple(order_by_elem.collator ? order_by_elem.collator->getLocale() : std::string())).second)
|
||||
{
|
||||
unique_elems.emplace_back(elem);
|
||||
}
|
||||
}
|
||||
|
||||
if (unique_elems.size() < elems.size())
|
||||
elems = unique_elems;
|
||||
}
|
||||
|
||||
|
||||
void ExpressionAnalyzer::makeSetsForIndex()
|
||||
{
|
||||
if (storage && ast && storage->supportsIndexForIn())
|
||||
|
@ -817,12 +817,10 @@ static SortDescription getSortDescription(ASTSelectQuery & query)
|
||||
{
|
||||
SortDescription order_descr;
|
||||
order_descr.reserve(query.order_expression_list->children.size());
|
||||
for (ASTs::iterator it = query.order_expression_list->children.begin();
|
||||
it != query.order_expression_list->children.end();
|
||||
++it)
|
||||
for (const auto & elem : query.order_expression_list->children)
|
||||
{
|
||||
String name = (*it)->children.front()->getColumnName();
|
||||
const ASTOrderByElement & order_by_elem = typeid_cast<const ASTOrderByElement &>(**it);
|
||||
String name = elem->children.front()->getColumnName();
|
||||
const ASTOrderByElement & order_by_elem = typeid_cast<const ASTOrderByElement &>(*elem);
|
||||
|
||||
order_descr.emplace_back(name, order_by_elem.direction, order_by_elem.collator);
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
SELECT n FROM (SELECT number AS n FROM system.numbers LIMIT 1000000) ORDER BY n, n, n, n, n, n, n, n, n, n LIMIT 1000000, 1;
|
Loading…
Reference in New Issue
Block a user