diff --git a/src/Planner/Planner.cpp b/src/Planner/Planner.cpp index 95f80891986..2a9d06bc17b 100644 --- a/src/Planner/Planner.cpp +++ b/src/Planner/Planner.cpp @@ -1075,18 +1075,11 @@ void Planner::buildPlanForQueryNode() if (query_node.hasPrewhere()) { if (query_node.hasWhere()) - { - auto function_node = std::make_shared("and"); - auto and_function = FunctionFactory::instance().get("and", query_context); - function_node->getArguments().getNodes() = {query_node.getPrewhere(), query_node.getWhere()}; - function_node->resolveAsFunction(and_function->build(function_node->getArgumentColumns())); - query_node.getWhere() = std::move(function_node); - query_node.getPrewhere() = {}; - } + query_node.getWhere() = mergeConditionNodes({query_node.getPrewhere(), query_node.getWhere()}, query_context); else - { query_node.getWhere() = query_node.getPrewhere(); - } + + query_node.getPrewhere() = {}; } SelectQueryInfo select_query_info; @@ -1106,6 +1099,16 @@ void Planner::buildPlanForQueryNode() select_query_info.has_aggregates = !aggregate_function_nodes.empty(); select_query_info.need_aggregate = query_node.hasGroupBy() || !aggregate_function_nodes.empty(); + if (!select_query_info.need_aggregate && query_node.hasHaving()) + { + if (query_node.hasWhere()) + query_node.getWhere() = mergeConditionNodes({query_node.getWhere(), query_node.getHaving()}, query_context); + else + query_node.getWhere() = query_node.getHaving(); + + query_node.getHaving() = {}; + } + checkStoragesSupportTransactions(planner_context); collectTableExpressionData(query_tree, *planner_context); collectSets(query_tree, *planner_context); diff --git a/src/Planner/Utils.cpp b/src/Planner/Utils.cpp index 59d174c2877..fa6bd774960 100644 --- a/src/Planner/Utils.cpp +++ b/src/Planner/Utils.cpp @@ -8,6 +8,8 @@ #include +#include + #include #include @@ -308,4 +310,14 @@ bool queryHasWithTotalsInAnySubqueryInJoinTree(const QueryTreeNodePtr & query_no return false; } +QueryTreeNodePtr mergeConditionNodes(const QueryTreeNodes & condition_nodes, const ContextPtr & context) +{ + auto function_node = std::make_shared("and"); + auto and_function = FunctionFactory::instance().get("and", context); + function_node->getArguments().getNodes() = condition_nodes; + function_node->resolveAsFunction(and_function->build(function_node->getArgumentColumns())); + + return function_node; +} + } diff --git a/src/Planner/Utils.h b/src/Planner/Utils.h index da99a7e62df..3ec1ed3a947 100644 --- a/src/Planner/Utils.h +++ b/src/Planner/Utils.h @@ -59,4 +59,7 @@ bool queryHasArrayJoinInJoinTree(const QueryTreeNodePtr & query_node); */ bool queryHasWithTotalsInAnySubqueryInJoinTree(const QueryTreeNodePtr & query_node); +/// Returns `and` function node that has condition nodes as its arguments +QueryTreeNodePtr mergeConditionNodes(const QueryTreeNodes & condition_nodes, const ContextPtr & context); + }