diff --git a/src/Interpreters/ExtractExpressionInfoVisitor.cpp b/src/Interpreters/ExtractExpressionInfoVisitor.cpp index c730f49fe90..75e94de0db5 100644 --- a/src/Interpreters/ExtractExpressionInfoVisitor.cpp +++ b/src/Interpreters/ExtractExpressionInfoVisitor.cpp @@ -27,8 +27,14 @@ void ExpressionInfoMatcher::visit(const ASTFunction & ast_function, const ASTPtr const auto & function = FunctionFactory::instance().tryGet(ast_function.name, data.context); /// Skip lambda, tuple and other special functions - if (function && function->isStateful()) - data.is_stateful_function = true; + if (function) + { + if (function->isStateful()) + data.is_stateful_function = true; + + if (!function->isDeterministicInScopeOfQuery()) + data.is_deterministic_function = false; + } } } diff --git a/src/Interpreters/ExtractExpressionInfoVisitor.h b/src/Interpreters/ExtractExpressionInfoVisitor.h index a412704edcc..0cb43e5b00a 100644 --- a/src/Interpreters/ExtractExpressionInfoVisitor.h +++ b/src/Interpreters/ExtractExpressionInfoVisitor.h @@ -21,6 +21,7 @@ struct ExpressionInfoMatcher bool is_array_join = false; bool is_stateful_function = false; bool is_aggregate_function = false; + bool is_deterministic_function = true; std::unordered_set unique_reference_tables_pos = {}; }; diff --git a/src/Interpreters/PredicateExpressionsOptimizer.cpp b/src/Interpreters/PredicateExpressionsOptimizer.cpp index 86bdec628cd..d401e51a392 100644 --- a/src/Interpreters/PredicateExpressionsOptimizer.cpp +++ b/src/Interpreters/PredicateExpressionsOptimizer.cpp @@ -90,8 +90,8 @@ std::vector PredicateExpressionsOptimizer::extractTablesPredicates(const A ExpressionInfoVisitor::Data expression_info{.context = context, .tables = tables_with_columns}; ExpressionInfoVisitor(expression_info).visit(predicate_expression); - if (expression_info.is_stateful_function) - return {}; /// give up the optimization when the predicate contains stateful function + if (expression_info.is_stateful_function || !expression_info.is_deterministic_function) + return {}; /// Not optimized when predicate contains state function or indeterministic function if (!expression_info.is_array_join) { diff --git a/tests/queries/0_stateless/01582_deterministic_function_with_predicate.reference b/tests/queries/0_stateless/01582_deterministic_function_with_predicate.reference new file mode 100644 index 00000000000..a1b4bfdcc03 --- /dev/null +++ b/tests/queries/0_stateless/01582_deterministic_function_with_predicate.reference @@ -0,0 +1,11 @@ +SELECT count() +FROM +( + SELECT number + FROM + ( + SELECT number + FROM numbers(1000000) + ) + WHERE rand64() < (0.01 * 18446744073709552000.) +) diff --git a/tests/queries/0_stateless/01582_deterministic_function_with_predicate.sql b/tests/queries/0_stateless/01582_deterministic_function_with_predicate.sql new file mode 100644 index 00000000000..9f64c292a65 --- /dev/null +++ b/tests/queries/0_stateless/01582_deterministic_function_with_predicate.sql @@ -0,0 +1 @@ +EXPLAIN SYNTAX SELECT count(*) FROM ( SELECT number FROM ( SELECT number FROM numbers(1000000) ) WHERE rand64() < (0.01 * 18446744073709552000.));