2020-11-06 03:50:58 +00:00
|
|
|
#include <Storages/MergeTree/PartitionPruner.h>
|
2023-04-08 04:47:21 +00:00
|
|
|
#include <Common/logger_useful.h>
|
2020-11-06 03:50:58 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2023-01-22 17:02:38 +00:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
|
|
|
KeyCondition buildKeyCondition(const KeyDescription & partition_key, const SelectQueryInfo & query_info, ContextPtr context, bool strict)
|
|
|
|
{
|
|
|
|
if (context->getSettingsRef().allow_experimental_analyzer)
|
|
|
|
return {query_info.filter_actions_dag, context, partition_key.column_names, partition_key.expression, {}, true /* single_point */, strict};
|
|
|
|
|
|
|
|
return {query_info, context, partition_key.column_names, partition_key.expression, true /* single_point */, strict};
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
PartitionPruner::PartitionPruner(const StorageMetadataPtr & metadata, const SelectQueryInfo & query_info, ContextPtr context, bool strict)
|
|
|
|
: partition_key(MergeTreePartition::adjustPartitionKey(metadata, context))
|
|
|
|
, partition_condition(buildKeyCondition(partition_key, query_info, context, strict))
|
|
|
|
, useless(strict ? partition_condition.anyUnknownOrAlwaysTrue() : partition_condition.alwaysUnknownOrTrue())
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PartitionPruner::canBePruned(const IMergeTreeDataPart & part)
|
2020-11-06 03:50:58 +00:00
|
|
|
{
|
2021-02-10 14:12:49 +00:00
|
|
|
if (part.isEmpty())
|
2020-11-06 03:50:58 +00:00
|
|
|
return true;
|
2023-01-22 17:02:38 +00:00
|
|
|
|
2021-02-10 14:12:49 +00:00
|
|
|
const auto & partition_id = part.info.partition_id;
|
2023-01-22 17:02:38 +00:00
|
|
|
bool is_valid = false;
|
|
|
|
|
2020-11-06 03:50:58 +00:00
|
|
|
if (auto it = partition_filter_map.find(partition_id); it != partition_filter_map.end())
|
2023-01-22 17:02:38 +00:00
|
|
|
{
|
2020-11-06 03:50:58 +00:00
|
|
|
is_valid = it->second;
|
2023-01-22 17:02:38 +00:00
|
|
|
}
|
2020-11-06 03:50:58 +00:00
|
|
|
else
|
|
|
|
{
|
2021-02-10 14:12:49 +00:00
|
|
|
const auto & partition_value = part.partition.value;
|
2020-11-06 03:50:58 +00:00
|
|
|
std::vector<FieldRef> index_value(partition_value.begin(), partition_value.end());
|
2022-07-07 08:02:38 +00:00
|
|
|
for (auto & field : index_value)
|
|
|
|
{
|
|
|
|
// NULL_LAST
|
|
|
|
if (field.isNull())
|
|
|
|
field = POSITIVE_INFINITY;
|
|
|
|
}
|
2023-01-22 17:02:38 +00:00
|
|
|
|
2020-11-06 03:50:58 +00:00
|
|
|
is_valid = partition_condition.mayBeTrueInRange(
|
|
|
|
partition_value.size(), index_value.data(), index_value.data(), partition_key.data_types);
|
|
|
|
partition_filter_map.emplace(partition_id, is_valid);
|
2023-01-22 17:02:38 +00:00
|
|
|
|
2022-07-07 08:02:38 +00:00
|
|
|
if (!is_valid)
|
|
|
|
{
|
|
|
|
WriteBufferFromOwnString buf;
|
|
|
|
part.partition.serializeText(part.storage, buf, FormatSettings{});
|
|
|
|
LOG_TRACE(&Poco::Logger::get("PartitionPruner"), "Partition {} gets pruned", buf.str());
|
|
|
|
}
|
2020-11-06 03:50:58 +00:00
|
|
|
}
|
2023-01-22 17:02:38 +00:00
|
|
|
|
2020-11-06 03:50:58 +00:00
|
|
|
return !is_valid;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|