mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-19 22:22:00 +00:00
analyzer - apply limit and offset settings
This commit is contained in:
parent
b0424c1021
commit
ce2b044532
@ -233,6 +233,17 @@ QueryTreeNodePtr QueryTreeBuilder::buildSelectExpression(const ASTPtr & select_q
|
||||
auto select_settings = select_query_typed.settings();
|
||||
SettingsChanges settings_changes;
|
||||
|
||||
if (is_subquery)
|
||||
{
|
||||
if (const Settings & settings_ref = updated_context->getSettingsRef(); settings_ref.limit || settings_ref.offset)
|
||||
{
|
||||
Settings settings = updated_context->getSettings();
|
||||
settings.limit = 0;
|
||||
settings.offset = 0;
|
||||
updated_context->setSettings(settings);
|
||||
}
|
||||
}
|
||||
|
||||
if (select_settings)
|
||||
{
|
||||
auto & set_query = select_settings->as<ASTSetQuery &>();
|
||||
|
@ -216,12 +216,17 @@ public:
|
||||
limit_length = query_node.getLimit()->as<ConstantNode &>().getValue().safeGet<UInt64>();
|
||||
}
|
||||
|
||||
if (settings.limit)
|
||||
limit_length = limit_length ? std::min(limit_length, settings.limit.value) : settings.limit;
|
||||
|
||||
if (query_node.hasOffset())
|
||||
{
|
||||
/// Constness of offset is validated during query analysis stage
|
||||
limit_offset = query_node.getOffset()->as<ConstantNode &>().getValue().safeGet<UInt64>();
|
||||
}
|
||||
|
||||
limit_offset += settings.offset;
|
||||
|
||||
/// Partial sort can be done if there is LIMIT, but no DISTINCT, LIMIT WITH TIES, LIMIT BY, ARRAY JOIN
|
||||
if (limit_length != 0 &&
|
||||
!query_node.isDistinct() &&
|
||||
@ -720,7 +725,7 @@ bool addPreliminaryLimitOptimizationStepIfNeeded(QueryPlan & query_plan,
|
||||
|
||||
bool apply_limit = query_processing_info.getToStage() != QueryProcessingStage::WithMergeableStateAfterAggregation;
|
||||
bool apply_prelimit = apply_limit &&
|
||||
query_node.hasLimit() &&
|
||||
query_analysis_result.limit_length &&
|
||||
!query_node.isLimitWithTies() &&
|
||||
!query_node.isGroupByWithTotals() &&
|
||||
!query_analysis_result.query_has_with_totals_in_any_subquery_in_join_tree &&
|
||||
@ -767,7 +772,7 @@ void addPreliminarySortOrDistinctOrLimitStepsIfNeeded(QueryPlan & query_plan,
|
||||
* Otherwise we can take several equal values from different streams
|
||||
* according to limit and skip some distinct values.
|
||||
*/
|
||||
if (query_node.hasLimit() && query_node.isDistinct())
|
||||
if (query_analysis_result.limit_length && query_node.isDistinct())
|
||||
{
|
||||
addDistinctStep(query_plan,
|
||||
query_analysis_result,
|
||||
@ -785,7 +790,7 @@ void addPreliminarySortOrDistinctOrLimitStepsIfNeeded(QueryPlan & query_plan,
|
||||
addLimitByStep(query_plan, limit_by_analysis_result, query_node);
|
||||
}
|
||||
|
||||
if (query_node.hasLimit())
|
||||
if (query_analysis_result.limit_length)
|
||||
addPreliminaryLimitStep(query_plan, query_analysis_result, planner_context, true /*do_not_skip_offset*/);
|
||||
}
|
||||
|
||||
@ -1420,7 +1425,7 @@ void Planner::buildPlanForQueryNode()
|
||||
|
||||
bool apply_offset = query_processing_info.getToStage() != QueryProcessingStage::WithMergeableStateAfterAggregationAndLimit;
|
||||
|
||||
if (query_node.hasLimit() && query_node.isLimitWithTies() && apply_offset)
|
||||
if (query_analysis_result.limit_length && query_node.isLimitWithTies() && apply_offset)
|
||||
addLimitStep(query_plan, query_analysis_result, planner_context, query_node);
|
||||
|
||||
addExtremesStepIfNeeded(query_plan, planner_context);
|
||||
@ -1434,9 +1439,9 @@ void Planner::buildPlanForQueryNode()
|
||||
* This is the case for various optimizations for distributed queries,
|
||||
* and when LIMIT cannot be applied it will be applied on the initiator anyway.
|
||||
*/
|
||||
if (query_node.hasLimit() && apply_limit && !limit_applied && apply_offset)
|
||||
if (query_analysis_result.limit_length && apply_limit && !limit_applied && apply_offset)
|
||||
addLimitStep(query_plan, query_analysis_result, planner_context, query_node);
|
||||
else if (!limit_applied && apply_offset && query_node.hasOffset())
|
||||
else if (!limit_applied && apply_offset && query_analysis_result.limit_length)
|
||||
addOffsetStep(query_plan, query_analysis_result);
|
||||
|
||||
/// Project names is not done on shards, because initiator will not find columns in blocks
|
||||
|
@ -95,6 +95,8 @@ ContextPtr getViewContext(ContextPtr context)
|
||||
view_settings.max_result_rows = 0;
|
||||
view_settings.max_result_bytes = 0;
|
||||
view_settings.extremes = false;
|
||||
view_settings.limit = 0;
|
||||
view_settings.offset = 0;
|
||||
view_context->setSettings(view_settings);
|
||||
return view_context;
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
-- { echoOn }
|
||||
SET limit = 0;
|
||||
SELECT * FROM numbers(10);
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
SELECT * FROM numbers(10) SETTINGS limit=5, offset=2;
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
SELECT count(*) FROM (SELECT * FROM numbers(10));
|
||||
10
|
||||
SELECT count(*) FROM (SELECT * FROM numbers(10) SETTINGS limit=5);
|
||||
5
|
||||
SELECT count(*) FROM (SELECT * FROM numbers(10)) SETTINGS limit=5;
|
||||
10
|
||||
SELECT count(*) FROM view(SELECT * FROM numbers(10));
|
||||
10
|
||||
SELECT count(*) FROM view(SELECT * FROM numbers(10) SETTINGS limit=5);
|
||||
5
|
||||
SELECT count(*) FROM view(SELECT * FROM numbers(10)) SETTINGS limit=5;
|
||||
10
|
||||
SET limit = 3;
|
||||
SELECT * FROM numbers(10);
|
||||
0
|
||||
1
|
||||
2
|
||||
SELECT * FROM numbers(10) SETTINGS limit=5, offset=2;
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
SELECT count(*) FROM (SELECT * FROM numbers(10));
|
||||
10
|
||||
SELECT count(*) FROM (SELECT * FROM numbers(10) SETTINGS limit=5);
|
||||
5
|
||||
SELECT count(*) FROM (SELECT * FROM numbers(10)) SETTINGS limit=5;
|
||||
10
|
||||
SELECT count(*) FROM view(SELECT * FROM numbers(10));
|
||||
10
|
||||
SELECT count(*) FROM view(SELECT * FROM numbers(10) SETTINGS limit=5);
|
||||
5
|
||||
SELECT count(*) FROM view(SELECT * FROM numbers(10)) SETTINGS limit=5;
|
||||
10
|
24
tests/queries/0_stateless/02667_analyzer_limit_settings.sql
Normal file
24
tests/queries/0_stateless/02667_analyzer_limit_settings.sql
Normal file
@ -0,0 +1,24 @@
|
||||
SET allow_experimental_analyzer = 1;
|
||||
|
||||
-- { echoOn }
|
||||
SET limit = 0;
|
||||
|
||||
SELECT * FROM numbers(10);
|
||||
SELECT * FROM numbers(10) SETTINGS limit=5, offset=2;
|
||||
SELECT count(*) FROM (SELECT * FROM numbers(10));
|
||||
SELECT count(*) FROM (SELECT * FROM numbers(10) SETTINGS limit=5);
|
||||
SELECT count(*) FROM (SELECT * FROM numbers(10)) SETTINGS limit=5;
|
||||
SELECT count(*) FROM view(SELECT * FROM numbers(10));
|
||||
SELECT count(*) FROM view(SELECT * FROM numbers(10) SETTINGS limit=5);
|
||||
SELECT count(*) FROM view(SELECT * FROM numbers(10)) SETTINGS limit=5;
|
||||
|
||||
SET limit = 3;
|
||||
SELECT * FROM numbers(10);
|
||||
SELECT * FROM numbers(10) SETTINGS limit=5, offset=2;
|
||||
SELECT count(*) FROM (SELECT * FROM numbers(10));
|
||||
SELECT count(*) FROM (SELECT * FROM numbers(10) SETTINGS limit=5);
|
||||
SELECT count(*) FROM (SELECT * FROM numbers(10)) SETTINGS limit=5;
|
||||
SELECT count(*) FROM view(SELECT * FROM numbers(10));
|
||||
SELECT count(*) FROM view(SELECT * FROM numbers(10) SETTINGS limit=5);
|
||||
SELECT count(*) FROM view(SELECT * FROM numbers(10)) SETTINGS limit=5;
|
||||
-- { echoOff }
|
Loading…
Reference in New Issue
Block a user