| 461 | { |
| 462 | public: |
| 463 | QueryAnalysisResult(const QueryTreeNodePtr & query_tree, |
| 464 | const PlannerQueryProcessingInfo & query_processing_info, |
| 465 | const PlannerContextPtr & planner_context) |
| 466 | { |
| 467 | const auto & query_node = query_tree->as<QueryNode &>(); |
| 468 | const auto & query_context = planner_context->getQueryContext(); |
| 469 | const auto & settings = query_context->getSettingsRef(); |
| 470 | |
| 471 | aggregate_overflow_row = query_node.isGroupByWithTotals() && settings[Setting::max_rows_to_group_by] |
| 472 | && settings[Setting::group_by_overflow_mode] == OverflowMode::ANY && settings[Setting::totals_mode] != TotalsMode::AFTER_HAVING_EXCLUSIVE; |
| 473 | aggregate_final = query_processing_info.getToStage() > QueryProcessingStage::WithMergeableState |
| 474 | && !query_node.isGroupByWithTotals() && !query_node.isGroupByWithRollup() && !query_node.isGroupByWithCube(); |
| 475 | aggregation_with_rollup_or_cube_or_grouping_sets = query_node.isGroupByWithRollup() || query_node.isGroupByWithCube() || |
| 476 | query_node.isGroupByWithGroupingSets(); |
| 477 | aggregation_should_produce_results_in_order_of_bucket_number |
| 478 | = query_processing_info.getToStage() == QueryProcessingStage::WithMergeableState |
| 479 | && (settings[Setting::distributed_aggregation_memory_efficient] || settings[Setting::enable_memory_bound_merging_of_aggregation_results]); |
| 480 | |
| 481 | query_has_array_join_in_join_tree = queryHasArrayJoinInJoinTree(query_tree); |
| 482 | query_has_with_totals_in_any_subquery_in_join_tree = queryHasWithTotalsInAnySubqueryInJoinTree(query_tree); |
| 483 | |
| 484 | sort_description = extractSortDescription(query_node.getOrderByNode(), *planner_context); |
| 485 | |
| 486 | if (query_node.hasLimit()) |
| 487 | { |
| 488 | /// Constness of limit is validated during query analysis stage |
| 489 | std::tie(limit_length, fractional_limit, is_limit_length_negative) |
| 490 | = getLimitOffsetValue(query_node.getLimit()->as<ConstantNode &>().getValue()); |
| 491 | |
| 492 | if (query_node.hasOffset() && (limit_length || fractional_limit > 0)) |
| 493 | { |
| 494 | /// Constness of offset is validated during query analysis stage |
| 495 | std::tie(limit_offset, fractional_offset, is_limit_offset_negative) |
| 496 | = getLimitOffsetValue(query_node.getOffset()->as<ConstantNode &>().getValue()); |
| 497 | } |
| 498 | } |
| 499 | else if (query_node.hasOffset()) |
| 500 | { |
| 501 | /// Constness of offset is validated during query analysis stage |
| 502 | std::tie(limit_offset, fractional_offset, is_limit_offset_negative) |
| 503 | = getLimitOffsetValue(query_node.getOffset()->as<ConstantNode &>().getValue()); |
| 504 | } |
| 505 | |
| 506 | /// Partial sort can be done if there is LIMIT, but no DISTINCT, LIMIT WITH TIES, LIMIT BY, ARRAY JOIN, NEGATIVE LIMIT, FRACTIONAL LIMIT/OFFSET |
| 507 | if (limit_length != 0 && |
| 508 | !query_node.isDistinct() && |
| 509 | !query_node.isLimitWithTies() && |
| 510 | !query_node.hasLimitBy() && |
| 511 | !query_has_array_join_in_join_tree && |
| 512 | fractional_offset == 0 && |
| 513 | fractional_limit == 0 && |
| 514 | limit_length <= std::numeric_limits<UInt64>::max() - limit_offset && |
| 515 | !is_limit_length_negative) |
| 516 | { |
| 517 | partial_sorting_limit = limit_length + limit_offset; |
| 518 | } |
| 519 | |
| 520 | if (query_node.hasLimitBy()) |
nothing calls this directly
no test coverage detected