mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Added support for LIMIT BY arbitary expressions [#CLICKHOUSE-3613] #1947
This commit is contained in:
parent
e604be2799
commit
f7e0912d81
@ -2529,6 +2529,24 @@ bool ExpressionAnalyzer::appendOrderBy(ExpressionActionsChain & chain, bool only
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExpressionAnalyzer::appendLimitBy(ExpressionActionsChain & chain, bool only_types)
|
||||
{
|
||||
assertSelect();
|
||||
|
||||
if (!select_query->limit_by_expression_list)
|
||||
return false;
|
||||
|
||||
initChain(chain, aggregated_columns);
|
||||
ExpressionActionsChain::Step & step = chain.steps.back();
|
||||
|
||||
getRootActions(select_query->limit_by_expression_list, only_types, false, step.actions);
|
||||
|
||||
for (const auto & child : select_query->limit_by_expression_list->children)
|
||||
step.required_output.push_back(child->getColumnName());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExpressionAnalyzer::appendProjectResult(ExpressionActionsChain & chain) const
|
||||
{
|
||||
assertSelect();
|
||||
|
@ -111,6 +111,7 @@ public:
|
||||
bool appendHaving(ExpressionActionsChain & chain, bool only_types);
|
||||
void appendSelect(ExpressionActionsChain & chain, bool only_types);
|
||||
bool appendOrderBy(ExpressionActionsChain & chain, bool only_types);
|
||||
bool appendLimitBy(ExpressionActionsChain & chain, bool only_types);
|
||||
/// Deletes all columns except mentioned by SELECT, arranges the remaining columns and renames them to aliases.
|
||||
void appendProjectResult(ExpressionActionsChain & chain) const;
|
||||
|
||||
|
@ -286,6 +286,10 @@ InterpreterSelectQuery::AnalysisResult InterpreterSelectQuery::analyzeExpression
|
||||
res.before_order_and_select = chain.getLastActions();
|
||||
chain.addStep();
|
||||
|
||||
query_analyzer->appendLimitBy(chain, !res.second_stage);
|
||||
res.before_limit_by = chain.getLastActions();
|
||||
chain.addStep();
|
||||
|
||||
query_analyzer->appendProjectResult(chain);
|
||||
res.final_projection = chain.getLastActions();
|
||||
|
||||
@ -456,9 +460,14 @@ void InterpreterSelectQuery::executeImpl(Pipeline & pipeline, const BlockInputSt
|
||||
if (need_second_distinct_pass)
|
||||
executeDistinct(pipeline, false, Names());
|
||||
|
||||
if (query.limit_by_expression_list)
|
||||
{
|
||||
executeExpression(pipeline, expressions.before_limit_by);
|
||||
executeLimitBy(pipeline);
|
||||
}
|
||||
|
||||
/** We must do projection after DISTINCT because projection may remove some columns.
|
||||
*/
|
||||
executeLimitBy(pipeline);
|
||||
executeProjection(pipeline, expressions.final_projection);
|
||||
|
||||
/** Extremes are calculated before LIMIT, but after LIMIT BY. This is Ok.
|
||||
@ -1029,7 +1038,7 @@ void InterpreterSelectQuery::executeLimitBy(Pipeline & pipeline)
|
||||
|
||||
Names columns;
|
||||
for (const auto & elem : query.limit_by_expression_list->children)
|
||||
columns.emplace_back(elem->getAliasOrColumnName());
|
||||
columns.emplace_back(elem->getColumnName());
|
||||
|
||||
size_t value = safeGet<UInt64>(typeid_cast<ASTLiteral &>(*query.limit_by_value).value);
|
||||
|
||||
|
@ -124,6 +124,7 @@ private:
|
||||
ExpressionActionsPtr before_aggregation;
|
||||
ExpressionActionsPtr before_having;
|
||||
ExpressionActionsPtr before_order_and_select;
|
||||
ExpressionActionsPtr before_limit_by;
|
||||
ExpressionActionsPtr final_projection;
|
||||
|
||||
/// Columns from the SELECT list, before renaming them to aliases.
|
||||
|
@ -0,0 +1,13 @@
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
0
|
||||
1
|
||||
5
|
||||
6
|
@ -0,0 +1,7 @@
|
||||
SELECT 1 FROM system.one LIMIT 1 BY 1;
|
||||
SELECT 1 FROM system.one LIMIT 1 BY 1 AS one;
|
||||
SELECT 1 as one FROM system.one LIMIT 1 BY 1;
|
||||
SELECT 1 as one FROM system.one LIMIT 1 BY one;
|
||||
SELECT 1 as one FROM system.one LIMIT 1 BY rand();
|
||||
SELECT number FROM numbers(10) LIMIT 2 BY number % 2;
|
||||
SELECT number FROM numbers(10) LIMIT 2 BY intDiv(number, 5);
|
Loading…
Reference in New Issue
Block a user