forked from ClickHouse/ClickHouse
-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathoptimizePrimaryKeyConditionAndLimit.cpp
More file actions
58 lines (51 loc) · 2.25 KB
/
optimizePrimaryKeyConditionAndLimit.cpp
File metadata and controls
58 lines (51 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <Processors/QueryPlan/Optimizations/Optimizations.h>
#include <Processors/QueryPlan/ExpressionStep.h>
#include <Processors/QueryPlan/FilterStep.h>
#include <Processors/QueryPlan/LimitStep.h>
#include <Processors/QueryPlan/SourceStepWithFilter.h>
#include <Processors/QueryPlan/ObjectFilterStep.h>
namespace DB::QueryPlanOptimizations
{
void optimizePrimaryKeyConditionAndLimit(const Stack & stack)
{
const auto & frame = stack.back();
auto * source_step_with_filter = dynamic_cast<SourceStepWithFilterBase *>(frame.node->step.get());
if (!source_step_with_filter)
return;
const auto & storage_prewhere_info = source_step_with_filter->getPrewhereInfo();
if (storage_prewhere_info)
{
source_step_with_filter->addFilter(storage_prewhere_info->prewhere_actions.clone(), storage_prewhere_info->prewhere_column_name);
if (storage_prewhere_info->row_level_filter)
source_step_with_filter->addFilter(storage_prewhere_info->row_level_filter->clone(), storage_prewhere_info->row_level_column_name);
}
for (auto iter = stack.rbegin() + 1; iter != stack.rend(); ++iter)
{
if (auto * filter_step = typeid_cast<FilterStep *>(iter->node->step.get()))
{
source_step_with_filter->addFilter(filter_step->getExpression().clone(), filter_step->getFilterColumnName());
}
else if (auto * limit_step = typeid_cast<LimitStep *>(iter->node->step.get()))
{
source_step_with_filter->setLimit(limit_step->getLimitForSorting());
break;
}
else if (typeid_cast<ExpressionStep *>(iter->node->step.get()))
{
/// Note: actually, plan optimizations merge Filter and Expression steps.
/// Ideally, chain should look like (Expression -> ...) -> (Filter -> ...) -> ReadFromStorage,
/// So this is likely not needed.
continue;
}
else if (auto * object_filter_step = typeid_cast<ObjectFilterStep *>(iter->node->step.get()))
{
source_step_with_filter->addFilter(object_filter_step->getExpression().clone(), object_filter_step->getFilterColumnName());
}
else
{
break;
}
}
source_step_with_filter->applyFilters();
}
}