From ff65ca42ad389cc9c0833d51fdf93db665f39e43 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 9 Nov 2022 18:12:01 +0000 Subject: [PATCH] Fix limit. --- .../Optimizations/optimizeReadInOrder.cpp | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Processors/QueryPlan/Optimizations/optimizeReadInOrder.cpp b/src/Processors/QueryPlan/Optimizations/optimizeReadInOrder.cpp index 83753c701c7..fb8c4b17a3e 100644 --- a/src/Processors/QueryPlan/Optimizations/optimizeReadInOrder.cpp +++ b/src/Processors/QueryPlan/Optimizations/optimizeReadInOrder.cpp @@ -147,13 +147,16 @@ void appendExpression(ActionsDAGPtr & dag, const ActionsDAGPtr & expression) /// This function builds a common DAG which is a gerge of DAGs from Filter and Expression steps chain. /// Additionally, build a set of fixed columns. -void buildSortingDAG(QueryPlan::Node & node, ActionsDAGPtr & dag, FixedColumns & fixed_columns) +void buildSortingDAG(QueryPlan::Node & node, ActionsDAGPtr & dag, FixedColumns & fixed_columns, size_t & limit) { IQueryPlanStep * step = node.step.get(); if (auto * reading = typeid_cast(step)) { if (const auto * prewhere_info = reading->getPrewhereInfo()) { + /// Should ignore limit if there is filtering. + limit = 0; + if (prewhere_info->prewhere_actions) { //std::cerr << "====== Adding prewhere " << std::endl; @@ -168,13 +171,24 @@ void buildSortingDAG(QueryPlan::Node & node, ActionsDAGPtr & dag, FixedColumns & if (node.children.size() != 1) return; - buildSortingDAG(*node.children.front(), dag, fixed_columns); + buildSortingDAG(*node.children.front(), dag, fixed_columns, limit); if (auto * expression = typeid_cast(step)) - appendExpression(dag, expression->getExpression()); + { + const auto & actions = expression->getExpression(); + + /// Should ignore limit because arrayJoin() can reduce the number of rows in case of empty array. + if (actions->hasArrayJoin()) + limit = 0; + + appendExpression(dag, actions); + } if (auto * filter = typeid_cast(step)) { + /// Should ignore limit if there is filtering. + limit = 0; + appendExpression(dag, filter->getExpression()); if (const auto * filter_expression = dag->tryFindInOutputs(filter->getFilterColumnName())) appendFixedColumnsFromFilterExpression(*filter_expression, fixed_columns); @@ -182,6 +196,11 @@ void buildSortingDAG(QueryPlan::Node & node, ActionsDAGPtr & dag, FixedColumns & if (auto * array_join = typeid_cast(step)) { + /// Should ignore limit because ARRAY JOIN can reduce the number of rows in case of empty array. + /// But in case of LEFT ARRAY JOIN the result number of rows is always bigger. + if (!array_join->arrayJoin()->is_left) + limit = 0; + const auto & array_joined_columns = array_join->arrayJoin()->columns; /// Remove array joined columns from outputs. @@ -725,7 +744,7 @@ InputOrderInfoPtr buildInputOrderInfo(SortingStep & sorting, QueryPlan::Node & n ActionsDAGPtr dag; FixedColumns fixed_columns; - buildSortingDAG(node, dag, fixed_columns); + buildSortingDAG(node, dag, fixed_columns, limit); if (dag && !fixed_columns.empty()) enreachFixedColumns(*dag, fixed_columns);