[WIP] Limit number of analyze for one query

This commit is contained in:
vdimir 2022-08-18 09:13:47 +00:00 committed by Vladimir C
parent 9abcfce529
commit 928adb2b38
4 changed files with 47 additions and 0 deletions

View File

@ -367,6 +367,27 @@ public:
// Top-level OpenTelemetry trace context for the query. Makes sense only for a query context. // Top-level OpenTelemetry trace context for the query. Makes sense only for a query context.
OpenTelemetryTraceContext query_trace_context; OpenTelemetryTraceContext query_trace_context;
/// Some counters for current query execution.
/// Most of them are workarounds and should be removed in the future.
struct KitchenSink
{
std::atomic<size_t> analyze_counter = 0;
KitchenSink() = default;
KitchenSink(const KitchenSink & rhs)
: analyze_counter(rhs.analyze_counter.load())
{}
KitchenSink & operator=(const KitchenSink & rhs)
{
analyze_counter = rhs.analyze_counter.load();
return *this;
}
};
KitchenSink kitchen_sink;
private: private:
using SampleBlockCache = std::unordered_map<std::string, Block>; using SampleBlockCache = std::unordered_map<std::string, Block>;
mutable SampleBlockCache sample_block_cache; mutable SampleBlockCache sample_block_cache;

View File

@ -98,6 +98,7 @@ namespace ErrorCodes
extern const int SAMPLING_NOT_SUPPORTED; extern const int SAMPLING_NOT_SUPPORTED;
extern const int ILLEGAL_FINAL; extern const int ILLEGAL_FINAL;
extern const int ILLEGAL_PREWHERE; extern const int ILLEGAL_PREWHERE;
extern const int TOO_DEEP_PIPELINE;
extern const int TOO_MANY_COLUMNS; extern const int TOO_MANY_COLUMNS;
extern const int LOGICAL_ERROR; extern const int LOGICAL_ERROR;
extern const int NOT_IMPLEMENTED; extern const int NOT_IMPLEMENTED;
@ -496,6 +497,14 @@ InterpreterSelectQuery::InterpreterSelectQuery(
auto analyze = [&] (bool try_move_to_prewhere) auto analyze = [&] (bool try_move_to_prewhere)
{ {
if (context->hasQueryContext())
{
std::atomic<size_t> & current_query_analyze_count = context->getQueryContext()->kitchen_sink.analyze_counter;
++current_query_analyze_count;
if (settings.max_pipeline_depth && current_query_analyze_count >= settings.max_pipeline_depth)
throw DB::Exception(ErrorCodes::TOO_DEEP_PIPELINE, "Query analyze overflow. Try to increase `max_pipeline_depth` or simplify the query");
}
/// Allow push down and other optimizations for VIEW: replace with subquery and rewrite it. /// Allow push down and other optimizations for VIEW: replace with subquery and rewrite it.
ASTPtr view_table; ASTPtr view_table;
if (view) if (view)
@ -639,6 +648,7 @@ InterpreterSelectQuery::InterpreterSelectQuery(
analyze(shouldMoveToPrewhere()); analyze(shouldMoveToPrewhere());
bool need_analyze_again = false; bool need_analyze_again = false;
if (analysis_result.prewhere_constant_filter_description.always_false || analysis_result.prewhere_constant_filter_description.always_true) if (analysis_result.prewhere_constant_filter_description.always_false || analysis_result.prewhere_constant_filter_description.always_true)
{ {
if (analysis_result.prewhere_constant_filter_description.always_true) if (analysis_result.prewhere_constant_filter_description.always_true)
@ -647,6 +657,7 @@ InterpreterSelectQuery::InterpreterSelectQuery(
query.setExpression(ASTSelectQuery::Expression::PREWHERE, std::make_shared<ASTLiteral>(0u)); query.setExpression(ASTSelectQuery::Expression::PREWHERE, std::make_shared<ASTLiteral>(0u));
need_analyze_again = true; need_analyze_again = true;
} }
if (analysis_result.where_constant_filter_description.always_false || analysis_result.where_constant_filter_description.always_true) if (analysis_result.where_constant_filter_description.always_false || analysis_result.where_constant_filter_description.always_true)
{ {
if (analysis_result.where_constant_filter_description.always_true) if (analysis_result.where_constant_filter_description.always_true)

View File

@ -0,0 +1,15 @@
-- Tags: long
-- https://github.com/ClickHouse/ClickHouse/issues/21557
SET max_pipeline_depth = 1000;
EXPLAIN SYNTAX
WITH
x AS ( SELECT number FROM numbers(10) ),
cross_sales AS (
SELECT 1 AS xx
FROM x, x AS d1, x AS d2, x AS d3, x AS d4, x AS d5, x AS d6, x AS d7, x AS d8, x AS d9
WHERE x.number = d9.number
)
SELECT xx FROM cross_sales WHERE xx = 2000; -- { serverError TOO_DEEP_PIPELINE }