MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / mainQueryNodeBlockSizeByLimit

Function mainQueryNodeBlockSizeByLimit

src/Planner/PlannerJoinTree.cpp:703–767  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

701}
702
703UInt64 mainQueryNodeBlockSizeByLimit(const SelectQueryInfo & select_query_info)
704{
705 // Since we support negative limit, query node field could potentially be Int64 implying negative value.
706 // So, we have to handle to separately
707 auto const & main_query_node = select_query_info.query_tree->as<QueryNode const &>();
708
709 /// Constness of limit and offset is validated during query analysis stage
710 UInt64 limit_length = 0;
711 if (main_query_node.hasLimit())
712 {
713 const auto & field = main_query_node.getLimit()->as<ConstantNode &>().getValue();
714
715 const bool is_uint64 = !convertFieldToType(field, DataTypeUInt64()).isNull();
716
717 // Negative LIMIT, skip optimization
718 if (!is_uint64)
719 return 0;
720
721 limit_length = field.safeGet<UInt64>();
722 }
723
724 UInt64 limit_offset = 0;
725 if (main_query_node.hasOffset())
726 {
727 const auto & field = main_query_node.getOffset()->as<ConstantNode &>().getValue();
728 const bool is_uint64 = !convertFieldToType(field, DataTypeUInt64()).isNull();
729
730 // Negative OFFSET, skip optimization
731 if (!is_uint64)
732 return 0;
733
734 limit_offset = field.safeGet<UInt64>();
735 }
736
737 /// `arrayJoin` in the projection expands one input row into several output rows after the
738 /// source has run. Capping the source to `limit + offset` rows would truncate input BEFORE
739 /// expansion, so hard consumers of `trivial_limit` (StorageLoop, system.zeros, generateRandom)
740 /// could drop output rows that the LIMIT should keep. See issue #82279 and the sibling guard
741 /// in `numbersLikeUtils::shouldPushdownLimit`. (The `ARRAY JOIN` clause is lowered to a
742 /// separate table expression in the analyzer, so it is not a single-table read and never
743 /// reaches this optimization.)
744 if (hasFunctionNode(main_query_node.getProjectionNode(), "arrayJoin"))
745 return 0;
746
747 /** If not specified DISTINCT, WHERE, GROUP BY, HAVING, ORDER BY, JOIN, LIMIT BY, LIMIT WITH TIES
748 * but LIMIT is specified with UInt64 value, and limit + offset < max_block_size,
749 * then as the block size we will use limit + offset (not to read more from the table than requested),
750 * and also set the number of threads to 1.
751 */
752 if (main_query_node.hasLimit()
753 && !main_query_node.isDistinct()
754 && !main_query_node.isLimitWithTies()
755 && !main_query_node.hasPrewhere()
756 && !main_query_node.hasWhere()
757 && select_query_info.filter_asts.empty()
758 && !main_query_node.hasGroupBy()
759 && !main_query_node.hasHaving()
760 && !main_query_node.hasOrderBy()

Callers 1

Calls 15

convertFieldToTypeFunction · 0.85
hasFunctionNodeFunction · 0.85
hasLimitMethod · 0.80
hasOffsetMethod · 0.80
isDistinctMethod · 0.80
isLimitWithTiesMethod · 0.80
hasGroupByMethod · 0.80
maxFunction · 0.50
getValueMethod · 0.45
getLimitMethod · 0.45
isNullMethod · 0.45
getOffsetMethod · 0.45

Tested by

no test coverage detected