MCPcopy Create free account
hub / github.com/ByConity/ByConity / canReadInPartitionOrder

Function canReadInPartitionOrder

src/QueryPlan/ReadFromMergeTree.cpp:172–257  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

170}
171
172static bool canReadInPartitionOrder(
173 const StorageInMemoryMetadata & metadata,
174 const InputOrderInfo & input_order_info,
175 const ASTSelectQuery & select)
176{
177 if (!metadata.isPartitionKeyDefined() || !metadata.isSortingKeyDefined())
178 return false;
179
180 const auto & partition_key = metadata.getPartitionKey();
181 Names minmax_columns = partition_key.expression->getRequiredColumns();
182 /// for simplicity, only support table with one partition key
183 if (partition_key.column_names.size() != 1 || minmax_columns.size() != 1)
184 return false;
185
186 String partition_column = minmax_columns[0];
187 Names sorting_columns = metadata.getSortingKeyColumns();
188 chassert(sorting_columns.size() >= input_order_info.order_key_prefix_descr.size());
189 /// optimizer guarantees that order_key_prefix is a prefix of sorting columns
190 sorting_columns.resize(input_order_info.order_key_prefix_descr.size());
191
192 /// sorting columns should contain partition column
193 auto partition_column_it = std::find(sorting_columns.begin(), sorting_columns.end(), partition_column);
194 if (partition_column_it == sorting_columns.end())
195 return false;
196
197 /// Allow table "partition by c order by (a, b, c)" for query "where a={} and b={} order by c",
198 /// where all sorting columns before partition column match single value,
199 /// note that in this case, input order is (a, b, c)
200 if (partition_column_it != sorting_columns.begin())
201 {
202 NameSet single_value_columns;
203 auto collect = [&](const ASTPtr & filter)
204 {
205 if (!filter)
206 return;
207
208 for (const auto & conjunct : PredicateUtils::extractConjuncts(filter->clone()))
209 {
210 const auto * func = conjunct->as<ASTFunction>();
211 if (!func || func->name != "equals")
212 continue;
213 const auto * column = func->arguments->children[0]->as<ASTIdentifier>();
214 const auto * literal = func->arguments->children[1]->as<ASTLiteral>();
215 if (column && literal)
216 single_value_columns.insert(column->name());
217 }
218 };
219 collect(select.where());
220 collect(select.prewhere());
221 auto match_single_value = [&](const String & name) { return single_value_columns.count(name); };
222 if (!std::all_of(sorting_columns.begin(), partition_column_it, match_single_value))
223 return false;
224 }
225
226 /// fast path for: order by sort_column partition by sort_column
227 if (partition_key.column_names.front() == *partition_column_it)
228 return true;
229

Callers 1

initializePipelineMethod · 0.85

Calls 15

collectFunction · 0.85
isPartitionKeyDefinedMethod · 0.80
isSortingKeyDefinedMethod · 0.80
getPartitionKeyMethod · 0.80
getSortingKeyColumnsMethod · 0.80
prewhereMethod · 0.80
frontMethod · 0.80
findFunction · 0.50
getRequiredColumnsMethod · 0.45
sizeMethod · 0.45
resizeMethod · 0.45
beginMethod · 0.45

Tested by

no test coverage detected