Skip to content

Commit 9979b3d

Browse files
authored
Merge pull request #1129 from Altinity/backports/25.3.8/87303
25.3.8 Backport of ClickHouse#87303 - Fix condition not being moved to PREWHERE in case there is a row policy (version 2)
2 parents ca7fab7 + a87e4ba commit 9979b3d

38 files changed

+568
-367
lines changed

src/Interpreters/ExpressionAnalyzer.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,7 +1933,7 @@ ExpressionAnalysisResult::ExpressionAnalysisResult(
19331933
bool first_stage_,
19341934
bool second_stage_,
19351935
bool only_types,
1936-
const FilterDAGInfoPtr & filter_info_,
1936+
const FilterDAGInfoPtr & row_policy_info_,
19371937
const FilterDAGInfoPtr & additional_filter,
19381938
const Block & source_header)
19391939
: first_stage(first_stage_)
@@ -2031,10 +2031,10 @@ ExpressionAnalysisResult::ExpressionAnalysisResult(
20312031
columns_for_additional_filter.begin(), columns_for_additional_filter.end());
20322032
}
20332033

2034-
if (storage && filter_info_)
2034+
if (storage && row_policy_info_)
20352035
{
2036-
filter_info = filter_info_;
2037-
filter_info->do_remove_column = true;
2036+
row_policy_info = row_policy_info_;
2037+
row_policy_info->do_remove_column = true;
20382038
}
20392039

20402040
if (prewhere_dag_and_flags = query_analyzer.appendPrewhere(chain, !first_stage); prewhere_dag_and_flags)
@@ -2373,9 +2373,9 @@ std::string ExpressionAnalysisResult::dump() const
23732373
ss << "prewhere_info " << prewhere_info->dump() << "\n";
23742374
}
23752375

2376-
if (filter_info)
2376+
if (row_policy_info)
23772377
{
2378-
ss << "filter_info " << filter_info->dump() << "\n";
2378+
ss << "filter_info " << row_policy_info->dump() << "\n";
23792379
}
23802380

23812381
if (before_aggregation)

src/Interpreters/ExpressionAnalyzer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ struct ExpressionAnalysisResult
270270
NameSet columns_to_remove_after_prewhere;
271271

272272
PrewhereInfoPtr prewhere_info;
273-
FilterDAGInfoPtr filter_info;
273+
FilterDAGInfoPtr row_policy_info;
274274
ConstantFilterDescription prewhere_constant_filter_description;
275275
ConstantFilterDescription where_constant_filter_description;
276276
/// Actions by every element of ORDER BY
@@ -285,12 +285,12 @@ struct ExpressionAnalysisResult
285285
bool first_stage,
286286
bool second_stage,
287287
bool only_types,
288-
const FilterDAGInfoPtr & filter_info,
288+
const FilterDAGInfoPtr & row_policy_info,
289289
const FilterDAGInfoPtr & additional_filter, /// for setting additional_filters
290290
const Block & source_header);
291291

292292
/// Filter for row-level security.
293-
bool hasFilter() const { return filter_info.get(); }
293+
bool hasRowPolicyFilter() const { return row_policy_info.get(); }
294294

295295
bool hasJoin() const { return join.get(); }
296296
bool hasPrewhere() const { return prewhere_info.get(); }

src/Interpreters/InterpreterSelectQuery.cpp

Lines changed: 42 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,7 @@ InterpreterSelectQuery::InterpreterSelectQuery(
885885
/// Fix source_header for filter actions.
886886
if (row_policy_filter && !row_policy_filter->empty())
887887
{
888-
filter_info = generateFilterActions(
888+
row_policy_info = generateFilterActions(
889889
table_id, row_policy_filter->expression, context, storage, storage_snapshot, metadata_snapshot, required_columns,
890890
prepared_sets);
891891

@@ -1052,8 +1052,6 @@ bool InterpreterSelectQuery::adjustParallelReplicasAfterAnalysis()
10521052
max_rows = max_rows ? std::min(max_rows, settings[Setting::max_rows_to_read].value) : settings[Setting::max_rows_to_read];
10531053
query_info_copy.trivial_limit = max_rows;
10541054

1055-
/// Apply filters to prewhere and add them to the query_info so we can filter out parts efficiently during row estimation
1056-
applyFiltersToPrewhereInAnalysis(analysis_copy);
10571055
if (analysis_copy.prewhere_info)
10581056
{
10591057
query_info_copy.prewhere_info = analysis_copy.prewhere_info;
@@ -1069,13 +1067,13 @@ bool InterpreterSelectQuery::adjustParallelReplicasAfterAnalysis()
10691067
= query_info_copy.prewhere_info->prewhere_actions.findInOutputs(query_info_copy.prewhere_info->prewhere_column_name);
10701068
added_filter_nodes.nodes.push_back(&node);
10711069
}
1070+
}
10721071

1073-
if (query_info_copy.prewhere_info->row_level_filter)
1074-
{
1075-
const auto & node
1076-
= query_info_copy.prewhere_info->row_level_filter->findInOutputs(query_info_copy.prewhere_info->row_level_column_name);
1077-
added_filter_nodes.nodes.push_back(&node);
1078-
}
1072+
if (query_info_copy.row_level_filter)
1073+
{
1074+
const auto & node
1075+
= query_info_copy.row_level_filter->actions.findInOutputs(query_info_copy.row_level_filter->column_name);
1076+
added_filter_nodes.nodes.push_back(&node);
10791077
}
10801078

10811079
if (auto filter_actions_dag = ActionsDAG::buildFilterActionsDAG(added_filter_nodes.nodes))
@@ -1178,7 +1176,7 @@ Block InterpreterSelectQuery::getSampleBlockImpl()
11781176
&& options.to_stage > QueryProcessingStage::WithMergeableState;
11791177

11801178
analysis_result = ExpressionAnalysisResult(
1181-
*query_analyzer, metadata_snapshot, first_stage, second_stage, options.only_analyze, filter_info, additional_filter_info, source_header);
1179+
*query_analyzer, metadata_snapshot, first_stage, second_stage, options.only_analyze, row_policy_info, additional_filter_info, source_header);
11821180

11831181
if (options.to_stage == QueryProcessingStage::Enum::FetchColumns)
11841182
{
@@ -1621,32 +1619,20 @@ void InterpreterSelectQuery::executeImpl(QueryPlan & query_plan, std::optional<P
16211619
auto read_nothing = std::make_unique<ReadNothingStep>(source_header);
16221620
query_plan.addStep(std::move(read_nothing));
16231621

1624-
if (expressions.filter_info)
1622+
if (expressions.row_policy_info)
16251623
{
16261624
auto row_level_security_step = std::make_unique<FilterStep>(
16271625
query_plan.getCurrentHeader(),
1628-
expressions.filter_info->actions.clone(),
1629-
expressions.filter_info->column_name,
1630-
expressions.filter_info->do_remove_column);
1626+
expressions.row_policy_info->actions.clone(),
1627+
expressions.row_policy_info->column_name,
1628+
expressions.row_policy_info->do_remove_column);
16311629

16321630
row_level_security_step->setStepDescription("Row-level security filter");
16331631
query_plan.addStep(std::move(row_level_security_step));
16341632
}
16351633

16361634
if (expressions.prewhere_info)
16371635
{
1638-
if (expressions.prewhere_info->row_level_filter)
1639-
{
1640-
auto row_level_filter_step = std::make_unique<FilterStep>(
1641-
query_plan.getCurrentHeader(),
1642-
expressions.prewhere_info->row_level_filter->clone(),
1643-
expressions.prewhere_info->row_level_column_name,
1644-
true);
1645-
1646-
row_level_filter_step->setStepDescription("Row-level security filter (PREWHERE)");
1647-
query_plan.addStep(std::move(row_level_filter_step));
1648-
}
1649-
16501636
auto prewhere_step = std::make_unique<FilterStep>(
16511637
query_plan.getCurrentHeader(),
16521638
expressions.prewhere_info->prewhere_actions.clone(),
@@ -1748,13 +1734,13 @@ void InterpreterSelectQuery::executeImpl(QueryPlan & query_plan, std::optional<P
17481734
{
17491735
// If there is a storage that supports prewhere, this will always be nullptr
17501736
// Thus, we don't actually need to check if projection is active.
1751-
if (expressions.filter_info)
1737+
if (expressions.row_policy_info && !(!input_pipe && storage && storage->supportsPrewhere()))
17521738
{
17531739
auto row_level_security_step = std::make_unique<FilterStep>(
17541740
query_plan.getCurrentHeader(),
1755-
expressions.filter_info->actions.clone(),
1756-
expressions.filter_info->column_name,
1757-
expressions.filter_info->do_remove_column);
1741+
expressions.row_policy_info->actions.clone(),
1742+
expressions.row_policy_info->column_name,
1743+
expressions.row_policy_info->do_remove_column);
17581744

17591745
row_level_security_step->setStepDescription("Row-level security filter");
17601746
query_plan.addStep(std::move(row_level_security_step));
@@ -2194,21 +2180,20 @@ void InterpreterSelectQuery::addEmptySourceToQueryPlan(QueryPlan & query_plan, c
21942180
{
21952181
Pipe pipe(std::make_shared<NullSource>(source_header));
21962182

2183+
if (query_info.row_level_filter)
2184+
{
2185+
auto row_level_actions = std::make_shared<ExpressionActions>(query_info.row_level_filter->actions.clone());
2186+
pipe.addSimpleTransform([&](const Block & header)
2187+
{
2188+
return std::make_shared<FilterTransform>(header,
2189+
row_level_actions,
2190+
query_info.row_level_filter->column_name,
2191+
query_info.row_level_filter->do_remove_column);
2192+
});
2193+
}
21972194
if (query_info.prewhere_info)
21982195
{
21992196
auto & prewhere_info = *query_info.prewhere_info;
2200-
2201-
if (prewhere_info.row_level_filter)
2202-
{
2203-
auto row_level_actions = std::make_shared<ExpressionActions>(prewhere_info.row_level_filter->clone());
2204-
pipe.addSimpleTransform([&](const Block & header)
2205-
{
2206-
return std::make_shared<FilterTransform>(header,
2207-
row_level_actions,
2208-
prewhere_info.row_level_column_name, true);
2209-
});
2210-
}
2211-
22122197
auto filter_actions = std::make_shared<ExpressionActions>(prewhere_info.prewhere_actions.clone());
22132198
pipe.addSimpleTransform([&](const Block & header)
22142199
{
@@ -2247,38 +2232,9 @@ bool InterpreterSelectQuery::shouldMoveToPrewhere() const
22472232
return settings[Setting::optimize_move_to_prewhere] && (!query.final() || settings[Setting::optimize_move_to_prewhere_if_final]);
22482233
}
22492234

2250-
/// Note that this is const and accepts the analysis ref to be able to use it to do analysis for parallel replicas
2251-
/// without affecting the final analysis multiple times
2252-
void InterpreterSelectQuery::applyFiltersToPrewhereInAnalysis(ExpressionAnalysisResult & analysis) const
2253-
{
2254-
if (!analysis.filter_info)
2255-
return;
2256-
2257-
if (!analysis.prewhere_info)
2258-
{
2259-
const bool does_storage_support_prewhere = !input_pipe && storage && storage->supportsPrewhere();
2260-
if (does_storage_support_prewhere && shouldMoveToPrewhere())
2261-
{
2262-
/// Execute row level filter in prewhere as a part of "move to prewhere" optimization.
2263-
analysis.prewhere_info = std::make_shared<PrewhereInfo>(std::move(analysis.filter_info->actions), analysis.filter_info->column_name);
2264-
analysis.prewhere_info->remove_prewhere_column = std::move(analysis.filter_info->do_remove_column);
2265-
analysis.prewhere_info->need_filter = true;
2266-
analysis.filter_info = nullptr;
2267-
}
2268-
}
2269-
else
2270-
{
2271-
/// Add row level security actions to prewhere.
2272-
analysis.prewhere_info->row_level_filter = std::move(analysis.filter_info->actions);
2273-
analysis.prewhere_info->row_level_column_name = std::move(analysis.filter_info->column_name);
2274-
analysis.filter_info = nullptr;
2275-
}
2276-
}
2277-
2278-
22792235
void InterpreterSelectQuery::addPrewhereAliasActions()
22802236
{
2281-
applyFiltersToPrewhereInAnalysis(analysis_result);
2237+
auto & row_level_filter = analysis_result.row_policy_info;
22822238
auto & prewhere_info = analysis_result.prewhere_info;
22832239
auto & columns_to_remove_after_prewhere = analysis_result.columns_to_remove_after_prewhere;
22842240

@@ -2305,12 +2261,11 @@ void InterpreterSelectQuery::addPrewhereAliasActions()
23052261
/// Get some columns directly from PREWHERE expression actions
23062262
auto prewhere_required_columns = prewhere_info->prewhere_actions.getRequiredColumns().getNames();
23072263
columns.insert(prewhere_required_columns.begin(), prewhere_required_columns.end());
2308-
2309-
if (prewhere_info->row_level_filter)
2310-
{
2311-
auto row_level_required_columns = prewhere_info->row_level_filter->getRequiredColumns().getNames();
2312-
columns.insert(row_level_required_columns.begin(), row_level_required_columns.end());
2313-
}
2264+
}
2265+
if (row_level_filter)
2266+
{
2267+
auto row_level_required_columns = row_level_filter->actions.getRequiredColumns().getNames();
2268+
columns.insert(row_level_required_columns.begin(), row_level_required_columns.end());
23142269
}
23152270

23162271
return columns;
@@ -2468,13 +2423,15 @@ std::optional<UInt64> InterpreterSelectQuery::getTrivialCount(UInt64 allow_exper
24682423

24692424
// It's possible to optimize count() given only partition predicates
24702425
ActionsDAG::NodeRawConstPtrs filter_nodes;
2426+
if (analysis_result.hasRowPolicyFilter())
2427+
{
2428+
auto & row_level_filter = analysis_result.row_policy_info;
2429+
filter_nodes.push_back(&row_level_filter->actions.findInOutputs(row_level_filter->column_name));
2430+
}
24712431
if (analysis_result.hasPrewhere())
24722432
{
24732433
auto & prewhere_info = analysis_result.prewhere_info;
24742434
filter_nodes.push_back(&prewhere_info->prewhere_actions.findInOutputs(prewhere_info->prewhere_column_name));
2475-
2476-
if (prewhere_info->row_level_filter)
2477-
filter_nodes.push_back(&prewhere_info->row_level_filter->findInOutputs(prewhere_info->row_level_column_name));
24782435
}
24792436
if (analysis_result.hasWhere())
24802437
{
@@ -2665,10 +2622,11 @@ void InterpreterSelectQuery::executeFetchColumns(QueryProcessingStage::Enum proc
26652622
if (max_streams == 0)
26662623
max_streams = 1;
26672624

2668-
auto & prewhere_info = analysis_result.prewhere_info;
2625+
if (analysis_result.row_policy_info && (!input_pipe && storage && storage->supportsPrewhere()))
2626+
query_info.row_level_filter = analysis_result.row_policy_info;
26692627

2670-
if (prewhere_info)
2671-
query_info.prewhere_info = prewhere_info;
2628+
if (analysis_result.prewhere_info)
2629+
query_info.prewhere_info = analysis_result.prewhere_info;
26722630

26732631
bool optimize_read_in_order = analysis_result.optimize_read_in_order;
26742632
bool optimize_aggregation_in_order = analysis_result.optimize_read_in_order && !query_analyzer->useGroupingSetKey();

src/Interpreters/InterpreterSelectQuery.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ class InterpreterSelectQuery : public IInterpreterUnionOrSelectQuery
219219
ExpressionAnalysisResult analysis_result;
220220
/// For row-level security.
221221
RowPolicyFilterPtr row_policy_filter;
222-
FilterDAGInfoPtr filter_info;
222+
FilterDAGInfoPtr row_policy_info;
223223

224224
/// For additional_filter setting.
225225
FilterDAGInfoPtr additional_filter_info;

src/Interpreters/getHeaderForProcessingStage.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ Block getHeaderForProcessingStage(
103103
case QueryProcessingStage::FetchColumns:
104104
{
105105
Block header = storage_snapshot->getSampleBlockForColumns(column_names);
106-
header = SourceStepWithFilter::applyPrewhereActions(header, query_info.prewhere_info);
106+
header = SourceStepWithFilter::applyPrewhereActions(header, query_info.row_level_filter, query_info.prewhere_info);
107107
return header;
108108
}
109109
case QueryProcessingStage::WithMergeableState:

0 commit comments

Comments
 (0)