| 2106 | } |
| 2107 | |
| 2108 | void MergeTreeMetaBase::filterPartitionByTTL(std::vector<std::shared_ptr<MergeTreePartition>> & partition_list, time_t query_time) const |
| 2109 | { |
| 2110 | if (canFilterPartitionByTTL()) |
| 2111 | { |
| 2112 | const auto & metadata_snapshot = getInMemoryMetadataPtr(); |
| 2113 | if (!metadata_snapshot->hasRowsTTL()) |
| 2114 | return; |
| 2115 | |
| 2116 | /// make a copy of rows_ttl, we may rewrite it later. |
| 2117 | auto rows_ttl = metadata_snapshot->table_ttl.rows_ttl; |
| 2118 | |
| 2119 | /// Construct a block consists of partition keys then compute ttl values according to this block |
| 2120 | const auto & partition_key_sample = metadata_snapshot->getPartitionKey().sample_block; |
| 2121 | MutableColumns columns = partition_key_sample.cloneEmptyColumns(); |
| 2122 | |
| 2123 | for (const auto & partition : partition_list) |
| 2124 | { |
| 2125 | /// This can happen when ALTER query is implemented improperly; finish ALTER query should bypass this check. |
| 2126 | if (columns.size() != partition->value.size()) |
| 2127 | throw Exception( |
| 2128 | ErrorCodes::LOGICAL_ERROR, |
| 2129 | "Partition key columns definition missmatch between inmemory and metastore, this is a bug, expect block ({}), got values " |
| 2130 | "({})\n", |
| 2131 | partition_key_sample.dumpNames(), |
| 2132 | fmt::join(partition->value, ", ")); |
| 2133 | |
| 2134 | for (size_t i = 0; i < partition->value.size(); ++i) |
| 2135 | columns[i]->insert(partition->value[i]); |
| 2136 | } |
| 2137 | |
| 2138 | auto block = partition_key_sample.cloneWithColumns(std::move(columns)); |
| 2139 | TTLDescription::tryRewriteTTLWithPartitionKey(rows_ttl, metadata_snapshot->columns, metadata_snapshot->partition_key, metadata_snapshot->primary_key, getContext()); |
| 2140 | rows_ttl.expression->execute(block); |
| 2141 | |
| 2142 | // got the ttl values for each partition based on ttl expression |
| 2143 | const auto & ttl_values = block.getByName(rows_ttl.result_column); |
| 2144 | const IColumn * column = ttl_values.column.get(); |
| 2145 | |
| 2146 | if (column->size() != partition_list.size()) |
| 2147 | throw Exception("Calculated TTL column size cannot match input partitions column size.", ErrorCodes::LOGICAL_ERROR); |
| 2148 | |
| 2149 | if (query_time == 0) |
| 2150 | query_time = std::time(nullptr); |
| 2151 | |
| 2152 | std::vector<std::shared_ptr<MergeTreePartition>> filtered_result; |
| 2153 | |
| 2154 | if (column->isNullable()) |
| 2155 | column = static_cast<const ColumnNullable *>(column)->getNestedColumnPtr().get(); |
| 2156 | |
| 2157 | if (const ColumnUInt16 * column_date = typeid_cast<const ColumnUInt16 *>(column)) |
| 2158 | { |
| 2159 | const auto & date_lut = DateLUT::serverTimezoneInstance(); |
| 2160 | for (size_t index = 0; index < column->size(); index++) |
| 2161 | { |
| 2162 | auto ttl_value = date_lut.fromDayNum(DayNum(column_date->getElement(index))); |
| 2163 | if (ttl_value >= query_time) |
| 2164 | filtered_result.push_back(partition_list[index]); |
| 2165 | } |
no test coverage detected