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

Function matchSortDescriptionAndKey

src/Storages/ReadInOrderOptimizer.cpp:122–178  ·  view source on GitHub ↗

Optimize in case of exact match with order key element or in some simple cases when order key element is wrapped into monotonic function.

Source from the content-addressed store, hash-verified

120/// Optimize in case of exact match with order key element
121/// or in some simple cases when order key element is wrapped into monotonic function.
122MatchResult matchSortDescriptionAndKey(
123 const ExpressionActions::Actions & actions,
124 const SortColumnDescription & sort_column,
125 const String & sorting_key_column)
126{
127 /// If required order depend on collation, it cannot be matched with primary key order.
128 /// Because primary keys cannot have collations.
129 if (sort_column.collator)
130 return {};
131
132 MatchResult result{sort_column.direction, false};
133
134 /// For the path: order by (sort_column, ...)
135 if (sort_column.column_name == sorting_key_column)
136 return result;
137
138 /// For the path: order by (function(sort_column), ...)
139 /// Allow only one simple monotonic functions with one argument
140 /// Why not allow multi monotonic functions?
141 bool found_function = false;
142
143 for (const auto & action : actions)
144 {
145 if (action.node->type != ActionsDAG::ActionType::FUNCTION)
146 continue;
147
148 if (found_function)
149 return {};
150
151 found_function = true;
152 if (action.node->children.size() != 1 || action.node->children.at(0)->result_name != sorting_key_column)
153 return {};
154
155 const auto & func = *action.node->function_base;
156 if (!func.hasInformationAboutMonotonicity())
157 return {};
158
159 auto monotonicity = func.getMonotonicityForRange(*func.getArgumentTypes().at(0), {}, {});
160 if (!monotonicity.is_monotonic)
161 return {};
162
163 /// If function is not strict monotonic, it can break order
164 /// if it's not last in the prefix of sort description.
165 /// E.g. if we have ORDER BY (d, u) -- ('2020-01-01', 1), ('2020-01-02', 0), ('2020-01-03', 1)
166 /// ORDER BY (toStartOfMonth(d), u) -- ('2020-01-01', 1), ('2020-01-01', 0), ('2020-01-01', 1)
167 if (!monotonicity.is_strict)
168 result.is_last_key = true;
169
170 if (!monotonicity.is_positive)
171 result.direction *= -1;
172 }
173
174 if (!found_function)
175 return {};
176
177 return result;
178}
179

Callers 1

getInputOrderImplMethod · 0.85

Calls 5

getArgumentTypesMethod · 0.80
sizeMethod · 0.45
atMethod · 0.45

Tested by

no test coverage detected